facter 1.3.7 → 1.3.8

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of facter might be problematic. Click here for more details.

data/CHANGELOG CHANGED
@@ -1,3 +1,19 @@
1
+ 1.3.8:
2
+ Fixed Rdoc::usage bug on CentOS 5 - closed Puppet #753 and Facter #40
3
+
4
+ Added support to return multiple interfaces and their IP addresses and
5
+ MAC addressess as facts. Returns interface_interfacename and
6
+ macaddress_interfacename. Existing ipaddress and macaddress facts are
7
+ unchanged and still returned. Currently Linux only. Closes #6.
8
+
9
+ Added macaddress fact support for FreeBSD and OpenBSD - closes #37
10
+
11
+ Added hardwareisa support for *BSD platforms - closed #38
12
+
13
+ Facter now detects the Mandriva distribution - closes #39
14
+
15
+ Facter now correctly detects ipaddress on NetBSD - closes #42
16
+
1
17
  1.3.7:
2
18
  A couple of small bugfixes, including fixing Facter.flush so it correctly
3
19
  flushes cached values, and the mac address fact only returns one
data/Rakefile CHANGED
@@ -24,8 +24,8 @@ project = Rake::RedLabProject.new("facter") do |p|
24
24
  'etc/*'
25
25
  ]
26
26
 
27
- p.epmhosts = %w{culain}
28
- p.rpmhost = "fedora1"
27
+ #p.epmhosts = %w{culain}
28
+ #p.rpmhost = "fedora1"
29
29
  #p.sunpkghost = "sol10b"
30
30
  end
31
31
 
@@ -43,4 +43,4 @@ if project.has?(:epm)
43
43
  task.rubylibs = FileList.new('lib/**/*')
44
44
  end
45
45
  end
46
- # $Id: Rakefile 188 2007-01-19 22:36:53Z luke $
46
+ # $Id$
data/bin/facter CHANGED
@@ -6,7 +6,7 @@
6
6
  #
7
7
  # = Usage
8
8
  #
9
- # facter [-d|--debug] [-h|--help] [-v|--version] [fact] [fact] [...]
9
+ # facter [-d|--debug] [-h|--help] [-v|--version] [-y|--yaml] [fact] [fact] [...]
10
10
  #
11
11
  # = Description
12
12
  #
@@ -27,6 +27,9 @@
27
27
  # version::
28
28
  # Print the version and exit.
29
29
  #
30
+ # yaml::
31
+ # Emit facts in YAML format.
32
+ #
30
33
  # = Example
31
34
  #
32
35
  # facter kernel
@@ -46,6 +49,7 @@ require 'facter'
46
49
  $haveusage = true
47
50
 
48
51
  begin
52
+ require 'rdoc/ri/ri_paths'
49
53
  require 'rdoc/usage'
50
54
  rescue Exception
51
55
  $haveusage = false
@@ -21,7 +21,7 @@ class Facter
21
21
  include Comparable
22
22
  include Enumerable
23
23
 
24
- FACTERVERSION = '1.3.7'
24
+ FACTERVERSION = '1.3.8'
25
25
  # = Facter
26
26
  # Functions as a hash of 'facts' you might care about about your
27
27
  # system, such as mac address, IP address, Video card, etc.
@@ -229,7 +229,7 @@ class Facter
229
229
 
230
230
  @value = nil
231
231
 
232
- @ldapname = name
232
+ @ldapname = name.to_s
233
233
  end
234
234
 
235
235
  # Add a new resolution mechanism. This requires a block, which will then
@@ -473,7 +473,7 @@ class Facter
473
473
  # Set the name by which this parameter is known in LDAP. The default
474
474
  # is just the fact name.
475
475
  def setldapname(name)
476
- @fact.ldapname = name
476
+ @fact.ldapname = name.to_s
477
477
  end
478
478
 
479
479
  # Is this resolution mechanism suitable on the system in question?
@@ -618,16 +618,20 @@ class Facter
618
618
  setcode 'uname -r'
619
619
  end
620
620
 
621
- { "LSBRelease" => "^LSB Version:\t(.*)$",
622
- "LSBDistId" => "^Distributor ID:\t(.*)$",
623
- "LSBDistRelease" => "^Release:\t(.*)$",
624
- "LSBDistDescription" => "^Description:\t(.*)$",
625
- "LSBDistCodeName" => "^Codename:\t(.*)$"
621
+ { "LSBRelease" => %r{^LSB Version:\t(.*)$},
622
+ "LSBDistId" => %r{^Distributor ID:\t(.*)$},
623
+ "LSBDistRelease" => %r{^Release:\t(.*)$},
624
+ "LSBDistDescription" => %r{^Description:\t(.*)$},
625
+ "LSBDistCodeName" => %r{^Codename:\t(.*)$}
626
626
  }.each do |fact, pattern|
627
627
  Facter.add(fact) do
628
628
  setcode do
629
- output = Resolution.exec('lsb_release -a 2>/dev/null')
630
- if output =~ /#{pattern}/
629
+ unless defined?(@@lsbdata) and defined?(@@lsbtime) and (Time.now.to_i - @@lsbtime.to_i < 5)
630
+ type = nil
631
+ @@lsbtime = Time.now
632
+ @@lsbdata = Resolution.exec('lsb_release -a 2>/dev/null')
633
+ end
634
+ if pattern.match(@@lsbdata)
631
635
  $1
632
636
  else
633
637
  nil
@@ -636,15 +640,6 @@ class Facter
636
640
  end
637
641
  end
638
642
 
639
- Facter.add(:operatingsystem) do
640
- # Default to just returning the kernel as the operating system
641
- setcode do Facter[:kernel].value end
642
- end
643
-
644
- Facter.add(:operatingsystemrelease) do
645
- setcode do Facter[:kernelrelease].value end
646
- end
647
-
648
643
  Facter.add(:operatingsystem) do
649
644
  confine :kernel => :sunos
650
645
  setcode do "Solaris" end
@@ -659,6 +654,8 @@ class Facter
659
654
  "Gentoo"
660
655
  elsif FileTest.exists?("/etc/fedora-release")
661
656
  "Fedora"
657
+ elsif FileTest.exists?("/etc/mandriva-release")
658
+ "Mandriva"
662
659
  elsif FileTest.exists?("/etc/redhat-release")
663
660
  txt = File.read("/etc/redhat-release")
664
661
  if txt =~ /centos/i
@@ -672,6 +669,43 @@ class Facter
672
669
  end
673
670
  end
674
671
 
672
+ Facter.add(:operatingsystem) do
673
+ # Default to just returning the kernel as the operating system
674
+ setcode do Facter[:kernel].value end
675
+ end
676
+
677
+ Facter.add(:operatingsystemrelease) do
678
+ confine :operatingsystem => :fedora
679
+ setcode do
680
+ File::open("/etc/fedora-release", "r") do |f|
681
+ line = f.readline.chomp
682
+ if line =~ /\(Rawhide\)$/
683
+ "Rawhide"
684
+ elsif line =~ /release (\d+)/
685
+ $1
686
+ end
687
+ end
688
+ end
689
+ end
690
+
691
+ Facter.add(:operatingsystemrelease) do
692
+ confine :operatingsystem => :redhat
693
+ setcode do
694
+ File::open("/etc/redhat-release", "r") do |f|
695
+ line = f.readline.chomp
696
+ if line =~ /\(Rawhide\)$/
697
+ "Rawhide"
698
+ elsif line =~ /release (\d+)/
699
+ $1
700
+ end
701
+ end
702
+ end
703
+ end
704
+
705
+ Facter.add(:operatingsystemrelease) do
706
+ setcode do Facter[:kernelrelease].value end
707
+ end
708
+
675
709
  Facter.add(:hardwaremodel) do
676
710
  setcode 'uname -m'
677
711
  end
@@ -865,7 +899,9 @@ class Facter
865
899
  filepath = File.join(dir,file)
866
900
  if FileTest.file?(filepath)
867
901
  begin
868
- value = File.open(filepath).read.chomp.split(/\s+/)[1]
902
+ File.open(filepath) { |f|
903
+ value = f.read.chomp.split(/\s+/)[1]
904
+ }
869
905
  rescue
870
906
  value = nil
871
907
  end
@@ -883,7 +919,7 @@ class Facter
883
919
 
884
920
  Facter.add(:hardwareisa) do
885
921
  setcode 'uname -p', '/bin/sh'
886
- confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE Debian Gentoo}
922
+ confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE Debian Gentoo FreeBSD OpenBSD NetBSD}
887
923
  end
888
924
 
889
925
  Facter.add(:macaddress) do
@@ -898,6 +934,20 @@ class Facter
898
934
  end
899
935
  end
900
936
 
937
+ Facter.add(:macaddress) do
938
+ confine :operatingsystem => %w{FreeBSD OpenBSD}
939
+ setcode do
940
+ ether = []
941
+ output = %x{/sbin/ifconfig}
942
+ output.each {|s|
943
+ if s =~ /(?:ether|lladdr)\s+(\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)/
944
+ ether.push($1)
945
+ end
946
+ }
947
+ ether[0]
948
+ end
949
+ end
950
+
901
951
  Facter.add(:macaddress) do
902
952
  confine :kernel => :darwin
903
953
  setcode do
@@ -935,7 +985,7 @@ class Facter
935
985
  end
936
986
  end
937
987
  Facter.add(:ipaddress) do
938
- confine :kernel => %w{FreeBSD NetBSD OpenBSD solaris}
988
+ confine :kernel => %w{FreeBSD OpenBSD solaris}
939
989
  setcode do
940
990
  ip = nil
941
991
  output = %x{/sbin/ifconfig}
@@ -953,6 +1003,25 @@ class Facter
953
1003
  ip
954
1004
  end
955
1005
  end
1006
+ Facter.add(:ipaddress) do
1007
+ confine :kernel => %w{NetBSD}
1008
+ setcode do
1009
+ ip = nil
1010
+ output = %x{/sbin/ifconfig -a}
1011
+
1012
+ output.split(/^\S/).each { |str|
1013
+ if str =~ /inet ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
1014
+ tmp = $1
1015
+ unless tmp =~ /127\./
1016
+ ip = tmp
1017
+ break
1018
+ end
1019
+ end
1020
+ }
1021
+
1022
+ ip
1023
+ end
1024
+ end
956
1025
  Facter.add(:ipaddress) do
957
1026
  confine :kernel => %w{darwin}
958
1027
  setcode do
@@ -1071,4 +1140,4 @@ class Facter
1071
1140
  Facter.loadfacts
1072
1141
  end
1073
1142
 
1074
- # $Id: facter.rb 202 2007-03-21 16:44:44Z luke $
1143
+ # $Id$
@@ -0,0 +1,85 @@
1
+ #
2
+ # ipmess.rb
3
+ # Try to get additional Facts about the machine's network interfaces on Linux
4
+ #
5
+ # Original concept Copyright (C) 2007 psychedelys <psychedelys@gmail.com>
6
+ # Update and *BSD support (C) 2007 James Turnbull <james@lovedthanlost.net>
7
+ #
8
+ # This program is free software; you can redistribute it and/or
9
+ # modify it under the terms of the GNU General Public License
10
+ # as published by the Free Software Foundation (version 2 of the License)
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program; if not, write to the Free Software
17
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
18
+ #
19
+
20
+ if Facter.kernel == "Linux"
21
+
22
+ output = %x{/sbin/ifconfig -a}
23
+ int = nil
24
+ output.scan(/^(\w+)(\d+)/) { |str|
25
+ output_int = %x{/sbin/ifconfig #{str}}
26
+ int = "#{str}"
27
+ tmp1 = nil
28
+ tmp2 = nil
29
+ test = {}
30
+ output_int.each { |s|
31
+ int = "#{str}"
32
+ tmp1 = $1 if s =~ /inet addr:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
33
+ tmp2 = $1 if s =~ /(?:ether|HWaddr) (\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2})/
34
+ if tmp1 != nil && tmp2 != nil && int != "lo"
35
+ test["ipaddress_" + int] = tmp1
36
+ test["macaddress_" + int] = tmp2
37
+ int = nil
38
+ tmp1 = nil
39
+ tmp2 = nil
40
+ end
41
+ }
42
+ test.each{|name,fact|
43
+ Facter.add(name) do
44
+ confine :kernel => :linux
45
+ setcode do
46
+ fact
47
+ end
48
+ end
49
+ }
50
+ }
51
+ end
52
+
53
+ if Facter.kernel == "FreeBSD" || Facter.kernel == "OpenBSD" || Facter.kernel == "NetBSD"
54
+
55
+ output = %x{/sbin/ifconfig -a}
56
+ int = nil
57
+ output.scan(/^(\w+)(\d+):/) { |str|
58
+ output_int = %x{/sbin/ifconfig #{str}}
59
+ int = "#{str}"
60
+ tmp1 = nil
61
+ tmp2 = nil
62
+ test = {}
63
+ output_int.each { |s|
64
+ int = "#{str}"
65
+ tmp1 = $1 if s =~ /inet ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
66
+ tmp2 = $1 if s =~ /(?:ether|lladdr)\s+(\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)/
67
+ if tmp1 != nil && tmp2 != nil && int != "lo"
68
+ test["ipaddress_" + int] = tmp1
69
+ test["macaddress_" + int] = tmp2
70
+ int = nil
71
+ tmp1 = nil
72
+ tmp2 = nil
73
+ end
74
+ }
75
+ test.each{|name,fact|
76
+ Facter.add(name) do
77
+ confine :kernel => :linux
78
+ setcode do
79
+ fact
80
+ end
81
+ end
82
+ }
83
+ }
84
+ end
85
+
@@ -0,0 +1,84 @@
1
+ #
2
+ # macosx.rb
3
+ # Additional Facts coming from Mac OS X system_profiler command
4
+ #
5
+ # Copyright (C) 2007 Jeff McCune
6
+ # Author: Jeff McCune <jeff.mccune@northstarlabs.net>
7
+ #
8
+ # This program is free software; you can redistribute it and/or
9
+ # modify it under the terms of the GNU General Public License
10
+ # as published by the Free Software Foundation (version 2 of the License)
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program; if not, write to the Free Software
17
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
18
+
19
+ # Jeff McCune
20
+ # There's a lot more information coming out of system_profiler -xml
21
+ # We could add quite a bit more, but I didn't want to overload facter
22
+ # at this point in time.
23
+ # In particular, Installed Software might be an interesting addition.
24
+
25
+ module Facter::Macosx
26
+ require 'thread'
27
+ require 'facter/util/plist'
28
+
29
+ # JJM I'd really like to dynamically generate these methods
30
+ # by looking at the _name key of the _items dict for each _dataType
31
+
32
+ def self.hardware_overview
33
+ # JJM Perhaps we should cache the XML data in a "class" level object.
34
+ top_level_plist = Plist::parse_xml %x{/usr/sbin/system_profiler -xml SPHardwareDataType}
35
+ system_hardware = top_level_plist[0]['_items'][0]
36
+ system_hardware.delete '_name'
37
+ system_hardware
38
+ end
39
+
40
+ # SPSoftwareDataType
41
+ def self.os_overview
42
+ top_level_plist = Plist::parse_xml %x{/usr/sbin/system_profiler -xml SPSoftwareDataType}
43
+ os_stuff = top_level_plist[0]['_items'][0]
44
+ os_stuff.delete '_name'
45
+ os_stuff
46
+ end
47
+
48
+ def self.sw_vers
49
+ ver = Hash.new
50
+ [ "productName", "productVersion", "buildVersion" ].each do |option|
51
+ ver["macosx_#{option}"] = %x{sw_vers -#{option}}.strip
52
+ end
53
+ ver
54
+ end
55
+ end
56
+
57
+ if Facter.kernel == "Darwin"
58
+ Facter::Macosx.hardware_overview.each do |fact, value|
59
+ Facter.add("sp_#{fact}") do
60
+ confine :kernel => :darwin
61
+ setcode do
62
+ value
63
+ end
64
+ end
65
+ end
66
+
67
+ Facter::Macosx.os_overview.each do |fact, value|
68
+ Facter.add("sp_#{fact}") do
69
+ confine :kernel => :darwin
70
+ setcode do
71
+ value
72
+ end
73
+ end
74
+ end
75
+
76
+ Facter::Macosx.sw_vers.each do |fact, value|
77
+ Facter.add(fact) do
78
+ confine :kernel => :darwin
79
+ setcode do
80
+ value
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,48 @@
1
+ # Info about the manufacturer
2
+ #
3
+
4
+ module Facter::Manufacturer
5
+ def self.dmi_find_system_info(name)
6
+ return nil unless FileTest.exists?("/usr/sbin/dmidecode")
7
+
8
+ # Do not run the command more than every five seconds.
9
+ unless defined?(@data) and defined?(@time) and (Time.now.to_i - @time.to_i < 5)
10
+ @data = {}
11
+ type = nil
12
+ @time = Time.now
13
+ # It's *much* easier to just parse the whole darn file than
14
+ # to just match a chunk of it.
15
+ %x{/usr/sbin/dmidecode 2>/dev/null}.split("\n").each do |line|
16
+ case line
17
+ when /^(\S.+)$/
18
+ type = $1.chomp
19
+ @data[type] ||= {}
20
+ when /^\s+(\S.+): (\S.*)$/
21
+ unless type
22
+ next
23
+ end
24
+ @data[type][$1] = $2
25
+ end
26
+ end
27
+ end
28
+
29
+ if data = @data["System Information"]
30
+ data[name]
31
+ else
32
+ nil
33
+ end
34
+ end
35
+ end
36
+
37
+ # Add the facts to Facter
38
+
39
+ {:SerialNumber => "Serial Number",
40
+ :Manufacturer => "Manufacturer",
41
+ :ProductName=> "Product Name"}.each do |fact, name|
42
+ Facter.add(fact) do
43
+ confine :kernel => :linux
44
+ setcode do
45
+ Facter::Manufacturer.dmi_find_system_info(name)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,24 @@
1
+ #--
2
+ ##############################################################
3
+ # Copyright 2006, Ben Bleything <ben@bleything.net> and #
4
+ # Patrick May <patrick@hexane.org> #
5
+ # #
6
+ # Distributed under the MIT license. #
7
+ ##############################################################
8
+ #++
9
+ # = Plist
10
+ #
11
+ # This is the main file for plist. Everything interesting happens in Plist and Plist::Emit.
12
+
13
+ require 'base64'
14
+ require 'cgi'
15
+ require 'stringio'
16
+
17
+ require 'facter/util/plist/generator'
18
+ require 'facter/util/plist/parser'
19
+
20
+ module Plist
21
+ VERSION = '3.0.0'
22
+ end
23
+
24
+ # $Id: plist.rb 1781 2006-10-16 01:01:35Z luke $
@@ -0,0 +1,226 @@
1
+ #--###########################################################
2
+ # Copyright 2006, Ben Bleything <ben@bleything.net> and #
3
+ # Patrick May <patrick@hexane.org> #
4
+ # #
5
+ # Distributed under the MIT license. #
6
+ ##############################################################
7
+ #++
8
+ # See Plist::Emit.
9
+ module Plist
10
+ # === Create a plist
11
+ # You can dump an object to a plist in one of two ways:
12
+ #
13
+ # * <tt>Plist::Emit.dump(obj)</tt>
14
+ # * <tt>obj.to_plist</tt>
15
+ # * This requires that you mixin the <tt>Plist::Emit</tt> module, which is already done for +Array+ and +Hash+.
16
+ #
17
+ # The following Ruby classes are converted into native plist types:
18
+ # Array, Bignum, Date, DateTime, Fixnum, Float, Hash, Integer, String, Symbol, Time, true, false
19
+ # * +Array+ and +Hash+ are both recursive; their elements will be converted into plist nodes inside the <array> and <dict> containers (respectively).
20
+ # * +IO+ (and its descendants) and +StringIO+ objects are read from and their contents placed in a <data> element.
21
+ # * User classes may implement +to_plist_node+ to dictate how they should be serialized; otherwise the object will be passed to <tt>Marshal.dump</tt> and the result placed in a <data> element.
22
+ #
23
+ # For detailed usage instructions, refer to USAGE[link:files/docs/USAGE.html] and the methods documented below.
24
+ module Emit
25
+ # Helper method for injecting into classes. Calls <tt>Plist::Emit.dump</tt> with +self+.
26
+ def to_plist(envelope = true)
27
+ return Plist::Emit.dump(self, envelope)
28
+ end
29
+
30
+ # Helper method for injecting into classes. Calls <tt>Plist::Emit.save_plist</tt> with +self+.
31
+ def save_plist(filename)
32
+ Plist::Emit.save_plist(self, filename)
33
+ end
34
+
35
+ # The following Ruby classes are converted into native plist types:
36
+ # Array, Bignum, Date, DateTime, Fixnum, Float, Hash, Integer, String, Symbol, Time
37
+ #
38
+ # Write us (via RubyForge) if you think another class can be coerced safely into one of the expected plist classes.
39
+ #
40
+ # +IO+ and +StringIO+ objects are encoded and placed in <data> elements; other objects are <tt>Marshal.dump</tt>'ed unless they implement +to_plist_node+.
41
+ #
42
+ # The +envelope+ parameters dictates whether or not the resultant plist fragment is wrapped in the normal XML/plist header and footer. Set it to false if you only want the fragment.
43
+ def self.dump(obj, envelope = true)
44
+ output = plist_node(obj)
45
+
46
+ output = wrap(output) if envelope
47
+
48
+ return output
49
+ end
50
+
51
+ # Writes the serialized object's plist to the specified filename.
52
+ def self.save_plist(obj, filename)
53
+ File.open(filename, 'wb') do |f|
54
+ f.write(obj.to_plist)
55
+ end
56
+ end
57
+
58
+ private
59
+ def self.plist_node(element)
60
+ output = ''
61
+
62
+ if element.respond_to? :to_plist_node
63
+ output << element.to_plist_node
64
+ else
65
+ case element
66
+ when Array
67
+ if element.empty?
68
+ output << "<array/>\n"
69
+ else
70
+ output << tag('array') {
71
+ element.collect {|e| plist_node(e)}
72
+ }
73
+ end
74
+ when Hash
75
+ if element.empty?
76
+ output << "<dict/>\n"
77
+ else
78
+ inner_tags = []
79
+
80
+ element.keys.sort.each do |k|
81
+ v = element[k]
82
+ inner_tags << tag('key', CGI::escapeHTML(k.to_s))
83
+ inner_tags << plist_node(v)
84
+ end
85
+
86
+ output << tag('dict') {
87
+ inner_tags
88
+ }
89
+ end
90
+ when true, false
91
+ output << "<#{element}/>\n"
92
+ when Time
93
+ output << tag('date', element.utc.strftime('%Y-%m-%dT%H:%M:%SZ'))
94
+ when Date # also catches DateTime
95
+ output << tag('date', element.strftime('%Y-%m-%dT%H:%M:%SZ'))
96
+ when String, Symbol, Fixnum, Bignum, Integer, Float
97
+ output << tag(element_type(element), CGI::escapeHTML(element.to_s))
98
+ when IO, StringIO
99
+ element.rewind
100
+ contents = element.read
101
+ # note that apple plists are wrapped at a different length then
102
+ # what ruby's base64 wraps by default.
103
+ # I used #encode64 instead of #b64encode (which allows a length arg)
104
+ # because b64encode is b0rked and ignores the length arg.
105
+ data = "\n"
106
+ Base64::encode64(contents).gsub(/\s+/, '').scan(/.{1,68}/o) { data << $& << "\n" }
107
+ output << tag('data', data)
108
+ else
109
+ output << comment( 'The <data> element below contains a Ruby object which has been serialized with Marshal.dump.' )
110
+ data = "\n"
111
+ Base64::encode64(Marshal.dump(element)).gsub(/\s+/, '').scan(/.{1,68}/o) { data << $& << "\n" }
112
+ output << tag('data', data )
113
+ end
114
+ end
115
+
116
+ return output
117
+ end
118
+
119
+ def self.comment(content)
120
+ return "<!-- #{content} -->\n"
121
+ end
122
+
123
+ def self.tag(type, contents = '', &block)
124
+ out = nil
125
+
126
+ if block_given?
127
+ out = IndentedString.new
128
+ out << "<#{type}>"
129
+ out.raise_indent
130
+
131
+ out << block.call
132
+
133
+ out.lower_indent
134
+ out << "</#{type}>"
135
+ else
136
+ out = "<#{type}>#{contents.to_s}</#{type}>\n"
137
+ end
138
+
139
+ return out.to_s
140
+ end
141
+
142
+ def self.wrap(contents)
143
+ output = ''
144
+
145
+ output << '<?xml version="1.0" encoding="UTF-8"?>' + "\n"
146
+ output << '<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' + "\n"
147
+ output << '<plist version="1.0">' + "\n"
148
+
149
+ output << contents
150
+
151
+ output << '</plist>' + "\n"
152
+
153
+ return output
154
+ end
155
+
156
+ def self.element_type(item)
157
+ return case item
158
+ when String, Symbol: 'string'
159
+ when Fixnum, Bignum, Integer: 'integer'
160
+ when Float: 'real'
161
+ else
162
+ raise "Don't know about this data type... something must be wrong!"
163
+ end
164
+ end
165
+ private
166
+ class IndentedString #:nodoc:
167
+ attr_accessor :indent_string
168
+
169
+ @@indent_level = 0
170
+
171
+ def initialize(str = "\t")
172
+ @indent_string = str
173
+ @contents = ''
174
+ end
175
+
176
+ def to_s
177
+ return @contents
178
+ end
179
+
180
+ def raise_indent
181
+ @@indent_level += 1
182
+ end
183
+
184
+ def lower_indent
185
+ @@indent_level -= 1 if @@indent_level > 0
186
+ end
187
+
188
+ def <<(val)
189
+ if val.is_a? Array
190
+ val.each do |f|
191
+ self << f
192
+ end
193
+ else
194
+ # if it's already indented, don't bother indenting further
195
+ unless val =~ /\A#{@indent_string}/
196
+ indent = @indent_string * @@indent_level
197
+
198
+ @contents << val.gsub(/^/, indent)
199
+ else
200
+ @contents << val
201
+ end
202
+
203
+ # it already has a newline, don't add another
204
+ @contents << "\n" unless val =~ /\n$/
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end
210
+
211
+ # we need to add this so sorting hash keys works properly
212
+ class Symbol #:nodoc:
213
+ def <=> (other)
214
+ self.to_s <=> other.to_s
215
+ end
216
+ end
217
+
218
+ class Array #:nodoc:
219
+ include Plist::Emit
220
+ end
221
+
222
+ class Hash #:nodoc:
223
+ include Plist::Emit
224
+ end
225
+
226
+ # $Id: generator.rb 1781 2006-10-16 01:01:35Z luke $
@@ -0,0 +1,227 @@
1
+ #--###########################################################
2
+ # Copyright 2006, Ben Bleything <ben@bleything.net> and #
3
+ # Patrick May <patrick@hexane.org> #
4
+ # #
5
+ # Distributed under the MIT license. #
6
+ ##############################################################
7
+ #++
8
+ # Plist parses Mac OS X xml property list files into ruby data structures.
9
+ #
10
+ # === Load a plist file
11
+ # This is the main point of the library:
12
+ #
13
+ # r = Plist::parse_xml( filename_or_xml )
14
+ module Plist
15
+ # Note that I don't use these two elements much:
16
+ #
17
+ # + Date elements are returned as DateTime objects.
18
+ # + Data elements are implemented as Tempfiles
19
+ #
20
+ # Plist::parse_xml will blow up if it encounters a data element.
21
+ # If you encounter such an error, or if you have a Date element which
22
+ # can't be parsed into a Time object, please send your plist file to
23
+ # plist@hexane.org so that I can implement the proper support.
24
+ def Plist::parse_xml( filename_or_xml )
25
+ listener = Listener.new
26
+ #parser = REXML::Parsers::StreamParser.new(File.new(filename), listener)
27
+ parser = StreamParser.new(filename_or_xml, listener)
28
+ parser.parse
29
+ listener.result
30
+ end
31
+
32
+ class Listener
33
+ #include REXML::StreamListener
34
+
35
+ attr_accessor :result, :open
36
+
37
+ def initialize
38
+ @result = nil
39
+ @open = Array.new
40
+ end
41
+
42
+
43
+ def tag_start(name, attributes)
44
+ @open.push PTag::mappings[name].new
45
+ end
46
+
47
+ def text( contents )
48
+ @open.last.text = contents if @open.last
49
+ end
50
+
51
+ def tag_end(name)
52
+ last = @open.pop
53
+ if @open.empty?
54
+ @result = last.to_ruby
55
+ else
56
+ @open.last.children.push last
57
+ end
58
+ end
59
+ end
60
+
61
+ class StreamParser
62
+ def initialize( filename_or_xml, listener )
63
+ @filename_or_xml = filename_or_xml
64
+ @listener = listener
65
+ end
66
+
67
+ TEXT = /([^<]+)/
68
+ XMLDECL_PATTERN = /<\?xml\s+(.*?)\?>*/um
69
+ DOCTYPE_PATTERN = /\s*<!DOCTYPE\s+(.*?)(\[|>)/um
70
+ COMMENT_START = /\A<!--/u
71
+ COMMENT_END = /.*?-->/um
72
+
73
+
74
+ def parse
75
+ plist_tags = PTag::mappings.keys.join('|')
76
+ start_tag = /<(#{plist_tags})([^>]*)>/i
77
+ end_tag = /<\/(#{plist_tags})[^>]*>/i
78
+
79
+ require 'strscan'
80
+
81
+ contents = (
82
+ if (File.exists? @filename_or_xml)
83
+ File.open(@filename_or_xml) {|f| f.read}
84
+ else
85
+ @filename_or_xml
86
+ end
87
+ )
88
+
89
+ @scanner = StringScanner.new( contents )
90
+ until @scanner.eos?
91
+ if @scanner.scan(COMMENT_START)
92
+ @scanner.scan(COMMENT_END)
93
+ elsif @scanner.scan(XMLDECL_PATTERN)
94
+ elsif @scanner.scan(DOCTYPE_PATTERN)
95
+ elsif @scanner.scan(start_tag)
96
+ @listener.tag_start(@scanner[1], nil)
97
+ if (@scanner[2] =~ /\/$/)
98
+ @listener.tag_end(@scanner[1])
99
+ end
100
+ elsif @scanner.scan(TEXT)
101
+ @listener.text(@scanner[1])
102
+ elsif @scanner.scan(end_tag)
103
+ @listener.tag_end(@scanner[1])
104
+ else
105
+ raise "Unimplemented element"
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ class PTag
112
+ @@mappings = { }
113
+ def PTag::mappings
114
+ @@mappings
115
+ end
116
+
117
+ def PTag::inherited( sub_class )
118
+ key = sub_class.to_s.downcase
119
+ key.gsub!(/^plist::/, '' )
120
+ key.gsub!(/^p/, '') unless key == "plist"
121
+
122
+ @@mappings[key] = sub_class
123
+ end
124
+
125
+ attr_accessor :text, :children
126
+ def initialize
127
+ @children = Array.new
128
+ end
129
+
130
+ def to_ruby
131
+ raise "Unimplemented: " + self.class.to_s + "#to_ruby on #{self.inspect}"
132
+ end
133
+ end
134
+
135
+ class PList < PTag
136
+ def to_ruby
137
+ children.first.to_ruby if children.first
138
+ end
139
+ end
140
+
141
+ class PDict < PTag
142
+ def to_ruby
143
+ dict = Hash.new
144
+ key = nil
145
+
146
+ children.each do |c|
147
+ if key.nil?
148
+ key = c.to_ruby
149
+ else
150
+ dict[key] = c.to_ruby
151
+ key = nil
152
+ end
153
+ end
154
+
155
+ dict
156
+ end
157
+ end
158
+
159
+ class PKey < PTag
160
+ def to_ruby
161
+ CGI::unescapeHTML(text || '')
162
+ end
163
+ end
164
+
165
+ class PString < PTag
166
+ def to_ruby
167
+ CGI::unescapeHTML(text || '')
168
+ end
169
+ end
170
+
171
+ class PArray < PTag
172
+ def to_ruby
173
+ children.collect do |c|
174
+ c.to_ruby
175
+ end
176
+ end
177
+ end
178
+
179
+ class PInteger < PTag
180
+ def to_ruby
181
+ text.to_i
182
+ end
183
+ end
184
+
185
+ class PTrue < PTag
186
+ def to_ruby
187
+ true
188
+ end
189
+ end
190
+
191
+ class PFalse < PTag
192
+ def to_ruby
193
+ false
194
+ end
195
+ end
196
+
197
+ class PReal < PTag
198
+ def to_ruby
199
+ text.to_f
200
+ end
201
+ end
202
+
203
+ require 'date'
204
+ class PDate < PTag
205
+ def to_ruby
206
+ DateTime.parse(text)
207
+ end
208
+ end
209
+
210
+ require 'base64'
211
+ class PData < PTag
212
+ def to_ruby
213
+ data = Base64.decode64(text.gsub(/\s+/, ''))
214
+
215
+ begin
216
+ return Marshal.load(data)
217
+ rescue Exception => e
218
+ io = StringIO.new
219
+ io.write data
220
+ io.rewind
221
+ return io
222
+ end
223
+ end
224
+ end
225
+ end
226
+
227
+ # $Id: parser.rb 1781 2006-10-16 01:01:35Z luke $
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.11
2
+ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: facter
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.3.7
7
- date: 2007-03-21 00:00:00 -05:00
6
+ version: 1.3.8
7
+ date: 2007-09-24 00:00:00 +02:00
8
8
  summary: Facter collects Operating system facts.
9
9
  require_paths:
10
10
  - lib
@@ -25,21 +25,28 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
25
25
  platform: ruby
26
26
  signing_key:
27
27
  cert_chain:
28
+ post_install_message:
28
29
  authors:
29
30
  -
30
31
  files:
31
32
  - install.rb
33
+ - COPYING
32
34
  - TODO
33
- - LICENSE
35
+ - INSTALL
34
36
  - Rakefile
35
37
  - README
38
+ - LICENSE
36
39
  - CHANGELOG
37
- - INSTALL
38
- - COPYING
39
40
  - bin/facter
40
41
  - lib/facter.rb
41
42
  - lib/facter/processor.rb
42
43
  - lib/facter/memory.rb
44
+ - lib/facter/util/plist.rb
45
+ - lib/facter/util/plist/parser.rb
46
+ - lib/facter/util/plist/generator.rb
47
+ - lib/facter/macosx.rb
48
+ - lib/facter/manufacturer.rb
49
+ - lib/facter/ipmess.rb
43
50
  - etc/facter.conf
44
51
  test_files: []
45
52