slack-utils 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rdoc ADDED
@@ -0,0 +1,77 @@
1
+ = slackware utilities
2
+
3
+ == Summary
4
+
5
+ A ruby library to access information on the Slackware Linux distribution
6
+
7
+ == Description
8
+
9
+ slack-utils
10
+
11
+ slp - shows installed slackware packages
12
+ with no args, it will show all.
13
+ or for each arg it will search the package names.
14
+
15
+ slf - search installed slackware packages for a file
16
+ this expects an arg(s), and will output, in grep fashion
17
+ packages matching your search args.
18
+
19
+ slt - mtime/install time of slackware packages
20
+ with no args, it will show all.
21
+ or for each arg it will search the package names.
22
+
23
+ sll - list the contents of packages matching the
24
+
25
+ slo - find files in /etc/, that have been orphaned and left behind
26
+ by unistalled/upgraded packages
27
+
28
+ slfindlinked - finds what is linked to your argument, and it's package
29
+ expects 1 argument passed.
30
+
31
+
32
+ TODO:
33
+ * 2010-08-20 09:16 <bailey> which is that I need to run a query to show
34
+ me what packages I'm running are different than the slack-current
35
+ versions, since I make local ones and forget about it
36
+ * enable `slf` to a relative path, and it determine the absolute path
37
+
38
+ == Installation
39
+
40
+ To install the gem
41
+ sudo gem install pkg/slack-utils-0.5.0.gem
42
+
43
+ == Quick Start
44
+
45
+ Install the gem as above.
46
+
47
+ Start using the library
48
+
49
+ $ irb
50
+ >> require 'rubygems'
51
+ >> require 'slackware'
52
+ >> pkg = Slackware::Packware.new()
53
+ >> pkg.name = "hello-kitty"
54
+ >> pkg.version = "1.0"
55
+
56
+ or
57
+ >> require 'rubygems'
58
+ >> require 'slackware'
59
+ >> tags = Slackware::System.tags_used
60
+ => ["SBo","alien","rlw"]
61
+
62
+ == Usage
63
+ === Show data
64
+
65
+ <b>Note: </b>
66
+
67
+ ==== Examples
68
+ see the exmamples/ files
69
+
70
+ == Help
71
+ There are many more methods than are documented on this page. Please explore
72
+ the RDOC to find more functionality.
73
+
74
+ For more complex examples, please see the examples directory
75
+ (GEM_ROOT/gems/slack-utils-<version>/examples/).
76
+
77
+ You can also contact me for more help or suggestions.
data/bin/slf ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'trollop'
5
+ require 'slackware/utils'
6
+
7
+ opts = Trollop::options do
8
+ banner <<-EOS
9
+
10
+ search for a file within installed Slackware package's FILE LIST.
11
+
12
+ Usage:
13
+ slf [options] [pkg search flags] <one of more files>
14
+
15
+ one or more files must be list
16
+ if no search flags, only names, then those only those matching entries are listed
17
+ EOS
18
+ opt :pkg, "Package PKGNAME (loose match)", :type => :string
19
+ opt :Version, "Package VERSION (loose match)", :type => :string
20
+ opt :arch, "Package ARCH (exact match)", :type => :string
21
+ opt :build, "Package BUILD (exact match)", :type => :string
22
+ opt :tag, "Package TAG (loose match)", :type => :string
23
+ end
24
+
25
+ if (ARGV.count > 0)
26
+ opts[:all] = true
27
+ end
28
+
29
+ if (ARGV.count == 0)
30
+ Trollop::die("one or more files must be provided")
31
+ end
32
+
33
+ begin
34
+ print_package_searched_files(build_packages(opts, []), ARGV)
35
+ rescue Interrupt
36
+ exit 0
37
+ rescue Exception => e
38
+ puts "ERROR: #{e.message}"
39
+ exit 1
40
+ end
41
+
data/bin/slfindlinked ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'slackware/utils'
5
+
6
+ print_find_linked(ARGV[0])
7
+
data/bin/sll ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'trollop'
5
+ require 'slackware/utils'
6
+
7
+ opts = Trollop::options do
8
+ banner <<-EOS
9
+
10
+ List owned files for a given Slackware package.
11
+
12
+ Usage:
13
+ sll [options] [search flags] [list of names]
14
+
15
+ if no search flags, only names, then those only those matching entries are listed
16
+
17
+ EOS
18
+ opt :pkg, "Package PKGNAME (loose match)", :type => :string
19
+ opt :Version, "Package VERSION (loose match)", :type => :string
20
+ opt :arch, "Package ARCH (exact match)", :type => :string
21
+ opt :build, "Package BUILD (exact match)", :type => :string
22
+ opt :tag, "Package TAG (loose match)", :type => :string
23
+ opt :force, "force me to show all files", :type => :boolean
24
+ end
25
+
26
+ # handing through that we are listing owned files
27
+ opts[:list_files] = true
28
+
29
+ if (opts.keys.grep(/[pkg|Version|arch|build|tag]_given$/).count == 0 && not(opts[:force]))
30
+ Trollop::die("force me if you really want to see all files ...")
31
+ end
32
+
33
+ begin
34
+ print_package_file_list(build_packages(opts, ARGV))
35
+ rescue Interrupt
36
+ exit 0
37
+ end
38
+
data/bin/slo ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'slackware/utils'
5
+
6
+
7
+ begin
8
+ print_orphaned_files(find_orphaned_config_files())
9
+ rescue Interrupt
10
+ exit 0
11
+ rescue Exception => e
12
+ puts "ERROR: #{e.message}"
13
+ exit 1
14
+ end
15
+
data/bin/slp ADDED
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'trollop'
5
+ require 'slackware/utils'
6
+
7
+ opts = Trollop::options do
8
+ banner <<-EOS
9
+
10
+ List installed Slackware packages.
11
+
12
+ Usage:
13
+ slp [options] [search flags] [list of names]
14
+
15
+ if no flags are used, then all entries are listed
16
+ if no search flags, only names, then those only those matching entries are listed
17
+
18
+ EOS
19
+ opt :color, "Colorize output", :type => :boolean
20
+ opt :pkg, "Package PKGNAME (loose match)", :type => :string
21
+ opt :Version, "Package VERSION (loose match)", :type => :string
22
+ opt :arch, "Package ARCH (exact match)", :type => :string
23
+ opt :build, "Package BUILD (exact match)", :type => :string
24
+ opt :tag, "Package TAG (loose match)", :type => :string
25
+ end
26
+
27
+ if (ARGV.count > 0)
28
+ opts[:all] = true
29
+ end
30
+
31
+ begin
32
+ print_packages(build_packages(opts, ARGV))
33
+ rescue Interrupt
34
+ exit 0
35
+ end
36
+
data/bin/slt ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'trollop'
5
+ require 'slackware/utils'
6
+
7
+ opts = Trollop::options do
8
+ banner <<-EOS
9
+
10
+ List (and search) installed Slackware package's times.
11
+
12
+ Usage:
13
+ slt [options] [search flags] [list of names]
14
+
15
+ if no flags are used, then all entries are listed
16
+ if no search flags, only names, then those only those matching entries are listed
17
+
18
+ EOS
19
+ opt :color, "Colorize output", :default => false, :type => :boolean
20
+ opt :epoch, "show time in seconds since 1970-01-01 00:00:00 UTC", :type => :boolean
21
+ opt :pkg, "Package PKGNAME (loose match)", :type => :string
22
+ opt :Version, "Package VERSION (loose match)", :type => :string
23
+ opt :arch, "Package ARCH (exact match)", :type => :string
24
+ opt :build, "Package BUILD (exact match)", :type => :string
25
+ opt :tag, "Package TAG (loose match)", :type => :string
26
+ end
27
+
28
+ # handing through that we are gathering times too
29
+ opts[:time] = true
30
+
31
+ if (opts.keys.grep(/[pkg|Version|arch|build|tag]_given$/).count == 0)
32
+ opts[:all] = true
33
+ end
34
+
35
+ begin
36
+ print_packages_times(build_packages(opts, ARGV), opts[:epoch])
37
+ rescue Interrupt
38
+ exit 0
39
+ end
40
+
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $: << File.absolute_path(File.dirname(__FILE__) + "/../lib")
4
+
5
+ require 'rubygems'
6
+ require 'slackware'
7
+
8
+ t = Time.now - 10000877
9
+ s = Slackware::System.installed_before(t)
10
+
11
+ puts "#{s.count} packages installed before #{t}"
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $: << File.absolute_path(File.dirname(__FILE__) + "/../lib")
4
+
5
+ require 'rubygems'
6
+ require 'slackware'
7
+
8
+ puts "tags used are: " + Slackware::System.tags_used.to_s
9
+
10
+ pkg = "kernel-modules"
11
+ if (Slackware::System.is_upgraded?(pkg))
12
+ puts pkg + " has been upgraded before"
13
+ Slackware::System.upgrades(pkg).each {|up| printf("%s upgraded from version %s\n", up.upgrade_time, up.version) }
14
+ else
15
+ puts pkg + " apparently has not ever been upgraded before"
16
+ end
17
+
data/examples/repo.rb ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/ruby -w
2
+
3
+ $: << File.absolute_path(File.dirname(__FILE__) + "/../lib")
4
+
5
+ require 'rubygems'
6
+ require 'slackware/repo'
7
+
8
+ sr = Slackware::Repo.new
9
+ sr.version = "current"
10
+
11
+ sr.set_packages
12
+
13
+ printf("%d packages in the slackware%s-%s repo\n", sr.packages.count, sr.arch, sr.version)
14
+
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $: << File.absolute_path(File.dirname(__FILE__) + "/../lib")
4
+
5
+ require 'rubygems'
6
+ require 'slackware'
7
+
8
+ pkgs = Slackware::System.installed_packages.map {|p| p.name }
9
+ sr = Slackware::Repo.new
10
+ sr.version = "current"
11
+ c = sr.get_changelog
12
+
13
+ printf("difference between current installation and %s...\n", sr.version)
14
+ printf("%d should be removed\n", (pkgs & c[:removed].map {|p| p.name }).count)
15
+ #p pkgs & c[:removed].map {|p| p.name }
16
+ ca = c[:added].map {|p| p.name }
17
+ printf("%d should be added\n", (ca.count - (pkgs & ca).count))
@@ -0,0 +1,193 @@
1
+
2
+ require 'time'
3
+
4
+ module Slackware
5
+ class Package
6
+ attr_accessor :time, :path, :file, :name, :version, :arch, :build, :tag, :tag_sep, :upgrade_time, :owned_files
7
+ def initialize(name = nil)
8
+ self.name = name
9
+ end
10
+
11
+ # pkg.parse instance method for parsing the package information
12
+ def parse(name)
13
+ if name.include?("/")
14
+ self.path = File.dirname(name)
15
+ name = File.basename(name)
16
+ end
17
+ if (name =~ RE_REMOVED_NAMES)
18
+ name = $1
19
+ self.upgrade_time = Time.strptime($2 + ' ' + $3, fmt='%F %H:%M:%S')
20
+ end
21
+ arr = name.split('-').reverse
22
+ build = arr.shift
23
+ if (build.include?("_"))
24
+ self.tag_sep = "_"
25
+ self.build = build.split(self.tag_sep)[0]
26
+ self.tag = build.split(self.tag_sep)[1..-1].join(self.tag_sep)
27
+ elsif (build =~ RE_BUILD_TAG)
28
+ self.build = $1
29
+ self.tag = $2
30
+ else
31
+ self.build = build
32
+ end
33
+ self.arch = arr.shift
34
+ self.version = arr.shift
35
+ self.name = arr.reverse.join('-')
36
+ end
37
+
38
+ # Package.parse class method
39
+ def self::parse(name)
40
+ p = self.new()
41
+ p.parse(name)
42
+ return p
43
+ end
44
+
45
+ # Reassemble the package name as it would be in file form
46
+ def fullname
47
+ if (self.upgrade_time)
48
+ time = self.upgrade_time.strftime("%F,%H:%M:%S")
49
+ return [self.name, self.version, self.arch, [self.build, self.tag].join(self.tag_sep), "upgraded", time].join("-")
50
+ else
51
+ return [self.name, self.version, self.arch, [self.build, self.tag].join(self.tag_sep)].join("-")
52
+ end
53
+ end
54
+
55
+ # Accessor for the PACKAGE DESCRIPTION from the package file
56
+ def package_description
57
+ if not(@package_description.nil?)
58
+ return @package_description
59
+ end
60
+
61
+ f = File.open(self.path + '/' + self.fullname)
62
+ while true
63
+ if (f.readline =~ /^PACKAGE DESCRIPTION:\s+(.*)$/)
64
+ desc = f.take_while {|l| not(l =~ /FILE LIST:/) }.map {|l| l.sub(/^#{self.name}:\s*/, '').chomp }
65
+ return desc
66
+ end
67
+ end
68
+ end
69
+
70
+ # Setter for the PACKAGE DESCRIPTION, in the event you are parsing a repo file
71
+ def package_description=(desc)
72
+ @package_description = desc
73
+ end
74
+
75
+ # Accessor for the PACKAGE LOCATION from the package file
76
+ def package_location
77
+ if not(@package_location.nil?)
78
+ return @package_location
79
+ end
80
+
81
+ f = File.open(self.path + '/' + self.fullname)
82
+ while true
83
+ if (f.readline =~ /^PACKAGE LOCATION:\s+(.*)$/)
84
+ return $1
85
+ end
86
+ end
87
+ end
88
+
89
+ # Setter for the PACKAGE LOCATION, in the event you are parsing a repo file
90
+ def package_location=(path)
91
+ @package_location = path
92
+ end
93
+
94
+ # Accessor for the UNCOMPRESSED PACKAGE SIZE from the package file
95
+ def uncompressed_size
96
+ if not(@uncompressed_size.nil?)
97
+ return @uncompressed_size
98
+ end
99
+
100
+ f = File.open(self.path + '/' + self.fullname)
101
+ while true
102
+ if (f.readline =~ /^UNCOMPRESSED PACKAGE SIZE:\s+(.*)$/)
103
+ return $1
104
+ end
105
+ end
106
+ end
107
+
108
+ # Setter for the UNCOMPRESSED PACKAGE SIZE, in the event you are parsing a repo file
109
+ def uncompressed_size=(size)
110
+ @uncompressed_size = size
111
+ end
112
+
113
+ # Accessor for the COMPRESSED PACKAGE SIZE from the package file
114
+ def compressed_size
115
+ if not(@compressed_size.nil?)
116
+ return @compressed_size
117
+ end
118
+
119
+ f = File.open(self.path + '/' + self.fullname)
120
+ while true
121
+ if (f.readline =~ /^COMPRESSED PACKAGE SIZE:\s+(.*)$/)
122
+ return $1
123
+ end
124
+ end
125
+ end
126
+
127
+ # Setter for the COMPRESSED PACKAGE SIZE, in the event you are parsing a repo file
128
+ def compressed_size=(size)
129
+ @compressed_size = size
130
+ end
131
+
132
+ # Accessor for the FILE LIST from the package file
133
+ # unless the :owned_files symbol is populated
134
+ def get_owned_files
135
+ if not(@owned_files.nil?)
136
+ return @owned_files
137
+ else
138
+ f = File.open(self.path + '/' + self.fullname)
139
+ files = f.drop_while {|l| not( l =~ /^FILE LIST:/) }[2..-1].map {|l| l.chomp }
140
+ f.close
141
+ return files
142
+ end
143
+ end
144
+
145
+ # Set the file list in the package object in memory
146
+ def set_owned_files
147
+ if @owned_files.nil?
148
+ @owned_files = self.get_owned_files
149
+ return true
150
+ else
151
+ return false
152
+ end
153
+ end
154
+
155
+ # populates and returns self.time
156
+ def get_time
157
+ if (self.time.nil? && self.path)
158
+ if (File.exist?(self.path + "/" + self.fullname))
159
+ self.time = File.mtime(self.path + "/" + self.fullname)
160
+ end
161
+ elsif (self.time.nil? && not(self.path))
162
+ if (File.exist?(DIR_INSTALLED_PACKAGES + "/" + self.fullname))
163
+ self.time = File.mtime(DIR_INSTALLED_PACKAGES + "/" + self.fullname)
164
+ end
165
+ end
166
+ return self.time
167
+ end
168
+
169
+ # Fill in the path information
170
+ def get_path
171
+ if (self.path.nil? && File.exist?(DIR_INSTALLED_PACKAGES + "/" + self.name))
172
+ self.path = DIR_INSTALLED_PACKAGE
173
+ return DIR_INSTALLED_PACKAGE
174
+ end
175
+ end
176
+
177
+ end
178
+
179
+ class Script < Package
180
+ attr_accessor :script
181
+
182
+ def initialize(name = nil)
183
+ self.script = true
184
+ super
185
+ end
186
+
187
+ def parse(name)
188
+ super
189
+ self.script = true
190
+ end
191
+
192
+ end
193
+ end
@@ -0,0 +1,142 @@
1
+
2
+ require 'slackware/package'
3
+ require 'slackware/system'
4
+ require 'net/http'
5
+ require 'net/ftp'
6
+ require 'rbconfig'
7
+
8
+ module Slackware
9
+
10
+ # Stub
11
+ class Repo
12
+ RE_PACKAGE_NAME = Regexp.new(/^PACKAGE NAME:\s+(.*)\.t[gbx]z\s*/)
13
+ RE_PACKAGE_LOCATION = Regexp.new(/^PACKAGE LOCATION:\s+(.*)$/)
14
+ RE_COMPRESSED_SIZE = Regexp.new(/^PACKAGE SIZE \(compressed\):\s+(.*)$/)
15
+ RE_UNCOMPRESSED_SIZE = Regexp.new(/^PACKAGE SIZE \(uncompressed\):\s+(.*)$/)
16
+
17
+ attr_accessor :proto, :mirror, :path, :version, :arch, :changelog, :packages
18
+
19
+ def initialize(repo = nil)
20
+ @packages = nil
21
+ if (repo.nil?)
22
+ self.proto = "ftp://"
23
+ self.mirror = "ftp.osuosl.org"
24
+ self.path = "/pub/slackware/"
25
+ self.version = begin
26
+ v = Slackware::System.version
27
+ if v =~ /(\d+)\.(\d+)\.\d+/
28
+ v = $1 + "." + $2
29
+ end
30
+ v
31
+ end
32
+ self.arch = begin
33
+ a = RbConfig::CONFIG["arch"]
34
+ if a =~ /x86_64/
35
+ a = "64"
36
+ else
37
+ a = ""
38
+ end
39
+ a
40
+ end
41
+ end
42
+ end
43
+
44
+ def fetch(file = nil)
45
+ if file.nil?
46
+ url = URI.parse(self.proto + self.mirror + self.path)
47
+ else
48
+ url = URI.parse(self.proto + self.mirror + self.path + file)
49
+ end
50
+ if self.proto =~ /ftp/
51
+ ftp = Net::FTP.open(self.mirror)
52
+ ftp.login
53
+ ftp.chdir(self.path + "slackware" + self.arch + "-" + self.version)
54
+ if (file.nil?)
55
+ data = ftp.list('*')
56
+ else
57
+ data = ftp.gettextfile(file, nil)
58
+ end
59
+ ftp.close
60
+ return data
61
+ elsif self.proto =~ /http/
62
+ # XXX this is not working yet
63
+ req = Net::HTTP::Get.new(url.path)
64
+ res = Net::HTTP.start(url.host, url.port) {|http| http.request(req) }
65
+ return res
66
+ else
67
+ return nil
68
+ end
69
+ end
70
+
71
+ # Pkg count that _should_ be removed
72
+ # pkgs = Slackware::System.installed_packages
73
+ # sr = Slackware::Repo.new
74
+ # sr.version = "current"
75
+ # c = get_changelog
76
+ #(pkgs.map {|p| p.fullname } & c[:removed].map {|p| p.fullname }).count
77
+ def get_changelog
78
+ if (@changelog.nil?)
79
+ changelog = {}
80
+ changelog_date = fetch("ChangeLog.txt").split(/\n/)
81
+ actions = %w{removed added upgraded rebuilt}
82
+ actions.each {|action|
83
+ changelog[:"#{action}"] = changelog_date.map {|line|
84
+ if line =~ /^\w+\/(.*)\.t[gx]z:\s+#{action}\.?$/i
85
+ Slackware::Package.parse($1)
86
+ end
87
+ }.compact
88
+ }
89
+ return changelog
90
+ else
91
+ return @changelog
92
+ end
93
+ end
94
+
95
+ def set_changelog
96
+ @changelog = get_changelog
97
+ return nil
98
+ end
99
+
100
+ def get_packages
101
+ if (@packages.nil?)
102
+ pkgs = []
103
+ fetch("PACKAGES.TXT").split(/\n\n/).each {|p_block|
104
+ p_block = p_block.split(/\n/).reject {|cell| cell if cell == "" }
105
+ if (p_block.shift =~ RE_PACKAGE_NAME)
106
+ pkg = Slackware::Package.parse($1)
107
+
108
+ p_block.shift =~ RE_PACKAGE_LOCATION
109
+ pkg.package_location = $1
110
+
111
+ p_block.shift =~ RE_COMPRESSED_SIZE
112
+ pkg.compressed_size = $1
113
+
114
+ p_block.shift =~ RE_UNCOMPRESSED_SIZE
115
+ pkg.uncompressed_size = $1
116
+
117
+ # This is the empty PACKAGE DESCRIPTON: tag
118
+ p_block.shift
119
+
120
+ pkg.package_description = p_block.map {|cell|
121
+ cell.sub(/^#{pkg.name}:\s*/, '')
122
+ }
123
+
124
+ pkgs << pkg
125
+ end
126
+ }
127
+ return pkgs
128
+ else
129
+ return @packages
130
+ end
131
+ end
132
+
133
+ def set_packages
134
+ @packages = get_packages
135
+ return nil
136
+ end
137
+
138
+ end
139
+
140
+
141
+ end
142
+
@@ -0,0 +1,165 @@
1
+
2
+ require 'slackware/package'
3
+
4
+ module Slackware
5
+
6
+ VERSION = begin
7
+ data = File.read("/etc/slackware-version")
8
+ data =~ /Slackware\s(.*)/
9
+ $1
10
+ rescue
11
+ nil
12
+ end
13
+
14
+ DIR_INSTALLED_PACKAGES = "/var/log/packages"
15
+ DIR_REMOVED_PACKAGES = "/var/log/removed_packages"
16
+ DIR_INSTALLED_SCRIPTS = "/var/log/scripts"
17
+ DIR_REMOVED_SCRIPTS = "/var/log/removed_scripts"
18
+ RE_REMOVED_NAMES = /^(.*)-upgraded-(\d{4}-\d{2}-\d{2}),(\d{2}:\d{2}:\d{2})$/
19
+ RE_BUILD_TAG = /^([[:digit:]]+)([[:alpha:]]+)$/
20
+
21
+ def self::version
22
+ VERSION
23
+ end
24
+
25
+ class System
26
+
27
+ def self::installed_packages
28
+ return Dir.glob(DIR_INSTALLED_PACKAGES + "/*").sort.map {|p| Slackware::Package.parse(p) }
29
+ end
30
+
31
+ def self::removed_packages
32
+ return Dir.glob(DIR_REMOVED_PACKAGES + "/*").sort.map {|p| Slackware::Package.parse(p) }
33
+ end
34
+
35
+ def self::installed_scripts
36
+ return Dir.glob(DIR_INSTALLED_SCRIPTS + "/*").sort.map {|s| Script.parse(s) }
37
+ end
38
+
39
+ def self::removed_scripts
40
+ return Dir.glob(DIR_REMOVED_SCRIPTS + "/*").sort.map {|s| Script.parse(s) }
41
+ end
42
+
43
+ def self::tags_used
44
+ return installed_packages.map {|p| p.tag }.uniq.compact
45
+ end
46
+
47
+ def self::with_tag(tag)
48
+ return installed_packages.map {|pkg| pkg if pkg.tag == tag }.compact
49
+ end
50
+
51
+ def self::arch_used
52
+ return installed_packages.map {|p| p.arch }.uniq.compact
53
+ end
54
+
55
+ def self::with_arch(arch)
56
+ return installed_packages.map {|pkg| pkg if pkg.arch == arch }.compact
57
+ end
58
+
59
+ def self::find_installed(name)
60
+ d = Dir.new(DIR_INSTALLED_PACKAGES)
61
+ return d.map {|p| Package.parse(p) if p.include?(name) }.compact
62
+ end
63
+
64
+ def self::find_removed(name)
65
+ d = Dir.new(DIR_REMOVED_PACKAGES)
66
+ return d.map {|p| Package.parse(p) if p.include?(name) }.compact
67
+ end
68
+
69
+ def self::upgrades(pkg)
70
+ if (m = find_removed(pkg).map {|p| p if (p.name == pkg) }.compact )
71
+ return m
72
+ else
73
+ return nil
74
+ end
75
+ end
76
+
77
+ # Return an Array of packages, that were installed after provided +time+
78
+ def self::installed_after(time)
79
+ arr = []
80
+ di = Dir.new(DIR_INSTALLED_PACKAGES)
81
+ di.each {|p|
82
+ if (File.mtime(DIR_INSTALLED_PACKAGES + "/" + p) >= time)
83
+ pkg = Package.parse(p)
84
+ pkg.get_time
85
+ arr << pkg
86
+ end
87
+ }
88
+ return arr
89
+ end
90
+
91
+ # Return an Array of packages, that were installed before provided +time+
92
+ def self::installed_before(time)
93
+ arr = []
94
+ di = Dir.new(DIR_INSTALLED_PACKAGES)
95
+ di.each {|p|
96
+ if (File.mtime(DIR_INSTALLED_PACKAGES + "/" + p) <= time)
97
+ pkg = Package.parse(p)
98
+ pkg.get_time
99
+ arr << pkg
100
+ end
101
+ }
102
+ return arr
103
+ end
104
+
105
+ # Return an Array of packages, that were removed after provided +time+
106
+ def self::removed_after(time)
107
+ arr = []
108
+ dr = Dir.new(DIR_REMOVED_PACKAGES)
109
+ dr.each {|p|
110
+ if (DIR_INSTALLED_PACKAGES + "/" + p =~ RE_REMOVED_NAMES)
111
+ if (Time.strptime($2 + ' ' + $3, fmt='%F %H:%M:%S') >= time)
112
+ arr << Package.parse(p)
113
+ end
114
+ end
115
+ }
116
+ return arr
117
+ end
118
+
119
+ # Return an Array of packages, that were removed before provided +time+
120
+ def self::removed_before(time)
121
+ arr = []
122
+ dr = Dir.new(DIR_REMOVED_PACKAGES)
123
+ dr.each {|p|
124
+ if (DIR_INSTALLED_PACKAGES + "/" + p =~ RE_REMOVED_NAMES)
125
+ if (Time.strptime($2 + ' ' + $3, fmt='%F %H:%M:%S') <= time)
126
+ arr << Package.parse(p)
127
+ end
128
+ end
129
+ }
130
+ return arr
131
+ end
132
+
133
+ # Check whether a given Slackware::Package has been upgraded before
134
+ def self::is_upgraded?(pkg)
135
+ if (find_removed(pkg).map {|p| p.name if p.upgrade_time }.include?(pkg) )
136
+ return true
137
+ else
138
+ return false
139
+ end
140
+ end
141
+
142
+ # Search installation of Slackware::Package's for what owns the questioned file
143
+ def self::owns_file(file)
144
+ pkgs = installed_packages
145
+ found_files = []
146
+ file = file.sub(/^\//, "") # clean off the leading '/'
147
+ re = Regexp::new(/#{file}/)
148
+ pkgs.each {|pkg|
149
+ if (found = pkg.owned_files.map {|f| f if f =~ re}.compact)
150
+ found.each {|f|
151
+ found_files << [pkg, f]
152
+ }
153
+ end
154
+ }
155
+ return found_files
156
+ end
157
+
158
+ # Return the version of Slackware Linux currently installed
159
+ def self::version
160
+ VERSION
161
+ end
162
+ end
163
+
164
+ end
165
+
@@ -0,0 +1,264 @@
1
+ #!/usr/bin/env ruby
2
+ # started - Fri Oct 9 15:48:43 CDT 2009
3
+ # updated for args - Tue Mar 23 14:54:19 CDT 2010
4
+ # Copyright 2009, 2010 Vincent Batts, http://hashbangbash.com/
5
+
6
+ require 'slackware'
7
+
8
+ # Variables
9
+ @st = "\033[31;1m"
10
+ @en = "\033[0m"
11
+
12
+ # Classes
13
+
14
+
15
+ # Functions
16
+ def build_packages(opts = {}, args = [])
17
+ pkgs = Slackware::System.installed_packages
18
+
19
+ if (opts[:time])
20
+ pkgs = pkgs.each {|p| p.get_time }
21
+ end
22
+ if (opts[:all])
23
+ if (args.count > 0)
24
+ selected_pkgs = []
25
+ args.each {|arg|
26
+ pkgs.each {|pkg|
27
+ if pkg.fullname =~ /#{arg}/
28
+ selected_pkgs << pkg
29
+ end
30
+ }
31
+ }
32
+ pkgs = selected_pkgs.uniq
33
+ selected_pkgs = nil
34
+ end
35
+ end
36
+ if (opts[:pkg_given])
37
+ pkgs = pkgs.map {|p|
38
+ re = /#{opts[:pkg]}/i
39
+ if p.name =~ re
40
+ if (opts[:color])
41
+ p.name = p.name.gsub(re, "#{@st}\\&#{@en}")
42
+ end
43
+ p
44
+ end
45
+ }.compact
46
+ end
47
+ if (opts[:Version_given])
48
+ pkgs = pkgs.map {|p|
49
+ re = Regexp.new(Regexp.escape(opts[:Version]))
50
+ if p.version =~ re
51
+ if (opts[:color])
52
+ p.version = p.version.gsub(re, "#{@st}\\&#{@en}")
53
+ end
54
+ p
55
+ end
56
+ }.compact
57
+ end
58
+ if (opts[:arch_given])
59
+ pkgs = pkgs.map {|p|
60
+ re = /#{opts[:arch]}/
61
+ if p.arch =~ re
62
+ if (opts[:color])
63
+ p.arch = p.arch.gsub(re, "#{@st}\\&#{@en}")
64
+ end
65
+ p
66
+ end
67
+ }.compact
68
+ end
69
+ if (opts[:build_given])
70
+ pkgs = pkgs.map {|p|
71
+ re = /#{opts[:build]}/
72
+ if p.build =~ re
73
+ if (opts[:color])
74
+ p.build = p.build.gsub(re, "#{@st}\\&#{@en}")
75
+ end
76
+ p
77
+ end
78
+ }.compact
79
+ end
80
+ if (opts[:tag_given])
81
+ pkgs = pkgs.map {|p|
82
+ re = /#{opts[:tag]}/i
83
+ if p.tag =~ re
84
+ if (opts[:color])
85
+ p.tag = p.tag.gsub(re, "#{@st}\\&#{@en}")
86
+ end
87
+ p
88
+ end
89
+ }.compact
90
+ end
91
+
92
+ return pkgs
93
+ end
94
+
95
+ def print_packages(pkgs)
96
+ if (pkgs.count > 0 && pkgs.first.class == Slackware::Package)
97
+ pkgs.each {|pkg|
98
+ printf("%s\n", pkg.fullname )
99
+ }
100
+ end
101
+ end
102
+
103
+ def print_packages_times(pkgs, epoch = false)
104
+ if (epoch == true)
105
+ pkgs.each {|pkg| printf("%s : %s\n", pkg.fullname, pkg.time.to_i) }
106
+ else
107
+ pkgs.each {|pkg| printf("%s : %s\n", pkg.fullname, pkg.time.to_s) }
108
+ end
109
+ end
110
+
111
+ # package file listing
112
+ def print_package_file_list(pkgs)
113
+ if (pkgs.count > 1)
114
+ pkgs.each {|pkg|
115
+ pkg.get_owned_files.each {|line|
116
+ puts pkg.name + ": " + line
117
+ }
118
+ }
119
+ else
120
+ pkgs.each {|pkg| puts pkg.get_owned_files }
121
+ end
122
+ end
123
+
124
+ # search Array of Slackware::Package's for files
125
+ # and print the items found
126
+ def print_package_searched_files(pkgs, files)
127
+ found_files = []
128
+ files.each {|file|
129
+ found_files = found_files.concat(Slackware::System.owns_file(file))
130
+ }
131
+ found_files.each {|file|
132
+ puts file[0].fullname + ": " + file[1]
133
+ }
134
+ end
135
+
136
+ # find orpaned files from /etc/
137
+ # * build a list of files from removed_packages
138
+ # * check the list to see if they are currently owned by a package
139
+ # * check the unowned members, to see if they still exist on the filesystem
140
+ # * return existing files
141
+ def find_orphaned_config_files
142
+ # build a list of config files currently installed
143
+ installed_config_files = Slackware::System.installed_packages.map {|pkg|
144
+ pkg.get_owned_files.map {|file|
145
+ file if (file =~ /^etc\// && not(file =~ /\/$/))
146
+ }
147
+ }.flatten.compact
148
+
149
+ # this Array is where we'll stash removed packages that have config file to check
150
+ pkgs = Array.new
151
+ Slackware::System.removed_packages.each {|r_pkg|
152
+ # find config files for this removed package
153
+ config = r_pkg.get_owned_files.grep(/^etc\/.*[\w|\d]$/)
154
+ # continue if there are none
155
+ if (config.count > 0)
156
+ # remove config files that are owned by a currently installed package
157
+ config = config.map {|file|
158
+ if (not(installed_config_files.include?(file)) && not(installed_config_files.include?(file + ".new")))
159
+ file
160
+ end
161
+ }.compact
162
+ # check again, and continue if there are no config files left
163
+ if (config.count > 0)
164
+ # otherwise add this package, and its files, to the stack
165
+ pkgs << {:pkg => r_pkg, :files => config}
166
+ end
167
+ end
168
+ }
169
+
170
+ # setup list of files to check whether they still exist on the filesystem
171
+ files = []
172
+ pkgs.map {|pkg| files << pkg[:files] }
173
+ files.flatten!.uniq!
174
+
175
+ orphaned_config_files = []
176
+ files.each {|file|
177
+ if (File.exist?("/" + file))
178
+ orphaned_config_files << file
179
+ end
180
+ }
181
+
182
+ return orphaned_config_files
183
+
184
+ end
185
+
186
+ def print_orphaned_files(files)
187
+ puts files
188
+ end
189
+
190
+ # XXX This is a work in progress
191
+ # It _works_, but is pretty darn slow ...
192
+ # It would be more efficient to break this out to a separate Class,
193
+ # and use a sqlite database for caching linked dependencies.
194
+ # Categorized by pkg, file, links. based on mtime of the package file,
195
+ # or maybe even mtime of the shared objects themselves.
196
+ # That way, those entries alone could be updated if they are newer,
197
+ # otherwise it's just a query.
198
+ def find_linked(file_to_find)
199
+ require 'find'
200
+
201
+ dirs = %w{ /lib /lib64 /usr/lib /usr/lib64 /bin /sbin /usr/bin /usr/sbin }
202
+ re_so = Regexp.new(/ELF.*shared object/)
203
+ re_exec = Regexp.new(/ELF.*executable/)
204
+
205
+ if File.exist?(file_to_find)
206
+ file_to_find = File.expand_path(file_to_find)
207
+ end
208
+ if not(filemagic(File.dirname(file_to_find) + "/" + File.readlink(file_to_find)) =~ re_so)
209
+ printf("%s is not a shared object\n",file_to_find)
210
+ return nil
211
+ end
212
+
213
+ includes_linked = []
214
+ printf("Searching through ... ")
215
+ dirs.each {|dir|
216
+ printf("%s ", dir)
217
+ Find.find(dir) {|file|
218
+ if File.directory?(file)
219
+ next
220
+ end
221
+ file_magic = filemagic(file)
222
+ if (file_magic =~ re_so || file_magic =~ re_exec)
223
+ l = `/usr/bin/ldd #{file} 2>/dev/null `
224
+ if l.include?(file_to_find)
225
+ printf(".")
226
+ l = l.sub(/\t/, '').split(/\n/)
227
+ includes_linked << {:file => file, :links => l}
228
+ end
229
+ end
230
+ }
231
+ }
232
+ printf("\n")
233
+ return includes_linked
234
+ end
235
+
236
+ # This is intended to take the return of the find_linked() method
237
+ def packages_of_linked_files(linked_files_arr)
238
+ pkgs = Slackware::System.installed_packages
239
+ owned_pkgs = []
240
+ pkgs.map {|pkg|
241
+ files.each {|file|
242
+ if pkg.owned_files.include?(file)
243
+ owned_pkgs << {:pkg => pkg, :file => file}
244
+ end
245
+ }
246
+ }
247
+ return owned_pkgs
248
+ end
249
+
250
+ # Pretty print the output of find_linked()
251
+ def print_find_linked(file_to_find)
252
+ files = find_linked(file_to_find)
253
+ printf("files linked to '%s' include:\n", file_to_find)
254
+ files.each {|file|
255
+ printf(" %s\n", file)
256
+ }
257
+ end
258
+
259
+ private
260
+
261
+ def filemagic(file)
262
+ return `/usr/bin/file "#{file}"`.chomp
263
+ end
264
+
data/lib/slackware.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'slackware/package'
2
+ require 'slackware/system'
3
+ require 'slackware/repo'
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: slack-utils
3
+ version: !ruby/object:Gem::Version
4
+ hash: 9
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 5
9
+ - 1
10
+ version: 0.5.1
11
+ platform: ruby
12
+ authors:
13
+ - Vincent Batts
14
+ autorequire: slack-utils
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-11-19 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: trollop
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description: " slack-utils is a means by which to access \n\
36
+ package information on the Slackware Linux OS. \n\
37
+ See the examples/ for more information.\n "
38
+ email: vbatts@hashbangbash.com
39
+ executables:
40
+ - slf
41
+ - slo
42
+ - sll
43
+ - slp
44
+ - slt
45
+ - slfindlinked
46
+ extensions: []
47
+
48
+ extra_rdoc_files:
49
+ - README.rdoc
50
+ files:
51
+ - README.rdoc
52
+ - bin/slf
53
+ - bin/slt
54
+ - bin/slp
55
+ - bin/slo
56
+ - bin/sll
57
+ - bin/slfindlinked
58
+ - examples/list_packages.rb
59
+ - examples/repo_difference.rb
60
+ - examples/before_then.rb
61
+ - examples/repo.rb
62
+ - lib/slackware.rb
63
+ - lib/slackware/utils.rb
64
+ - lib/slackware/package.rb
65
+ - lib/slackware/repo.rb
66
+ - lib/slackware/system.rb
67
+ has_rdoc: true
68
+ homepage: https://github.com/vbatts/slack-utils/
69
+ licenses: []
70
+
71
+ post_install_message:
72
+ rdoc_options:
73
+ - --main=README.rdoc
74
+ - --line-numbers
75
+ - --inline-source
76
+ - --title=Slackware utils (slack-utils) 0.5.1 Documentation
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ hash: 3
85
+ segments:
86
+ - 0
87
+ version: "0"
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ hash: 3
94
+ segments:
95
+ - 0
96
+ version: "0"
97
+ requirements: []
98
+
99
+ rubyforge_project:
100
+ rubygems_version: 1.3.7
101
+ signing_key:
102
+ specification_version: 3
103
+ summary: Accessing information for the Slackware Linux distribution
104
+ test_files: []
105
+