sysdeps 0.0.1 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. data/README +10 -2
  3. data/bin/sysdeps +30 -24
  4. data/changelog +22 -0
  5. data/lib/sysdeps.rb +31 -15
  6. metadata +3 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b049bc12869573168bae746e7dc2d32ef34208fa0345dbd22ff57db43d20123f
4
- data.tar.gz: a23f152be8710b210b2690beb713c7899747bbff45133fd2ac015b675df0ae95
3
+ metadata.gz: 12746c2ddf702510440de402f406f3079cb9fd6be551c38de245123d4d9a428e
4
+ data.tar.gz: b8bf4401086b5cfee95362c3773a5f2847237638b0ddb68eb4647897364b3f33
5
5
  SHA512:
6
- metadata.gz: 3d462d0039710534402652461f0cbfa54d39e7d1fcd5713af1a09dbdc273bec260ff467ce8e893eccffa2397e0a4109e5aac7cf62aeb76fb3ba7f32ad6a566f3
7
- data.tar.gz: a32ee64a4bf7803bebde727d817265b79912630a1e4731ec9acb522cd6bde0d84626dca7dbc76f8e820e33d8d86e700d15c561d948e61421d3e664b3c339da28
6
+ metadata.gz: ee340267f45ece6746b75826964dd293545fdb4c66e6a269d4c640742c3b34cb020f05e432523bd7457258cf5a72533e8a001818c7bfe39c70839a03178abb49
7
+ data.tar.gz: eb37503e553e676c0d35b6ebf2f6c57472ce19526430b0601cfa3cd1117578dd45a85574a290aeb768b4f6f359145d103793fad68c22e5a8c3ca4d02d2fa53e9
data/README CHANGED
@@ -7,13 +7,21 @@ A little script to find missing libraries on a Linux system
7
7
  -----------------------------------------------------------
8
8
 
9
9
 
10
- Usage: sysdeps [ -u ][ -p <program name | path> ][ -d <pattern> ][ -j ][ -h ]
10
+ Usage: sysdeps [ -u ][ -p <program name | path> ][ -d <pattern> ][ -j ][ -v ][ -h ]
11
11
  no args detects missing libraries
12
12
  -u build or update dapendencies cache
13
13
  -p <program name | path> prints program dependencies
14
14
  -d <pattern> prints programs which depends on <pattern> (regex)
15
15
  -j get results in JSON
16
+ -v print program version
16
17
  -h guess
17
18
 
18
-
19
19
  The dependencies cache must be built before. (sysdeps -u)
20
+
21
+ Ex usage: 'sysdeps -p dd -p tar -d dbus'
22
+
23
+ -----
24
+ Files
25
+ -----
26
+
27
+ Cache file is located under '~/.sysdeps_cache.json'
@@ -19,7 +19,7 @@ require 'json'
19
19
 
20
20
  include SysDeps
21
21
 
22
-
22
+ VERSION = '0.0.6'
23
23
  CACHE_PATH = ENV['HOME'] + '/.sysdeps_cache.json'
24
24
 
25
25
  KDEPENDENCIES = 'dependencies'.freeze
@@ -35,32 +35,33 @@ trap('INT') {
35
35
 
36
36
  help = ->() {
37
37
  STDERR.puts <<-EOF.gsub(/^\x20+/, '').gsub(/\x09/, ' ')
38
- Usage: #{File.basename $0} [ -u ][ -p <program name | path> ][ -d <pattern> ][ -j ][ -h ]
38
+ Usage: #{File.basename $0} [ -u ][ -p <program name | path> ][ -d <pattern> ][ -j ][ -v ][ -h ]
39
39
  \t\tno args detects missing libraries
40
40
  \t\t-u build or update dapendencies cache
41
41
  \t\t-p <program name | path> prints program dependencies
42
42
  \t\t-d <pattern> prints programs which depends on <pattern> (regex)
43
43
  \t\t-j get results in JSON
44
+ \t\t-v print program version
44
45
  \t\t-h guess
45
46
  EOF
46
47
  }
47
48
 
48
49
 
49
50
  build_cache = ->() {
50
- STDERR.print 'Collecting system libs infos ... '
51
- syslibs = SysDeps.get_syslibs ['/usr/lib', '/usr/libexec']
52
- STDERR.puts 'done'
51
+ STDERR.print 'Building cache ... '
52
+
53
+ syslibs = Thread.new { SysDeps.get_syslibs ['/proc', '/sys', '/dev'] }
54
+ prog_deps = Thread.new { get_programs_dependencies }
53
55
 
54
- STDERR.print 'Collecting dependencies of programs ... '
55
- prog_deps = get_programs_dependencies
56
- STDERR.puts 'done'
56
+ syslibs.join
57
+ lib_deps = Thread.new { get_libraries_dependencies syslibs.value }
58
+ prog_deps.join
59
+ lib_deps.join
57
60
 
58
- STDERR.print 'Collecting dependencies of libraries ... '
59
- lib_deps = get_libraries_dependencies syslibs
60
61
  STDERR.puts 'done'
61
62
 
62
63
  File.open(CACHE_PATH, 'w+') { |f|
63
- f.write({syslibs: syslibs, prog_deps: prog_deps, lib_deps: lib_deps}.to_json) }}
64
+ f.write({syslibs: syslibs.value, prog_deps: prog_deps.value, lib_deps: lib_deps.value}.to_json) }}
64
65
 
65
66
 
66
67
  get_data_from_cache = ->(path) {
@@ -100,9 +101,9 @@ missing_proc = ->() {
100
101
 
101
102
  depends_on = ->(patterns) {
102
103
  o = get_data_from_cache.call CACHE_PATH
103
- prog_deps = 'prog_deps'
104
+ deps = o['prog_deps'].merge(o['lib_deps'])
104
105
  patterns.each_with_object({KDEPENDON => {}}) { |p, obj|
105
- pbd = get_programs_by_deps(o[prog_deps], p)
106
+ pbd = get_programs_by_deps(deps, p)
106
107
  obj[KDEPENDON]["~#{p}"] = pbd if pbd }}
107
108
 
108
109
 
@@ -124,15 +125,19 @@ display_p_and_d_options = ->(prog_procs, deps_procs) {
124
125
  dependencies = result[KDEPENDENCIES]
125
126
  dependon = result[KDEPENDON]
126
127
 
127
- dependencies.each { |prog, deps|
128
- puts "#{prog}:"
129
- deps.each { |d| puts(("\x20" * 4) + d) }} unless dependencies.first.last.empty? rescue nil
128
+ if dependencies
129
+ dependencies.each { |prog, deps|
130
+ puts "#{prog}:"
131
+ deps.each { |d| puts(("\x20" * 4) + d) }}
132
+ end
130
133
 
131
- dependon.each { |pattern, match|
132
- puts "#{pattern}:"
133
- match.each { |lib, deps|
134
- puts(("\x20" * 4) + "#{lib}:")
135
- deps.each { |d| puts(("\x20" * 8) + d) }}} unless dependon.first.last.empty? rescue nil }
134
+ if dependon
135
+ dependon.each { |pattern, match|
136
+ puts "#{pattern}:" unless match.empty?
137
+ match.each { |lib, deps|
138
+ puts(("\x20" * 4) + "#{lib}:")
139
+ deps.each { |d| puts(("\x20" * 8) + d) }}}
140
+ end }
136
141
 
137
142
 
138
143
  main = ->{
@@ -149,10 +154,11 @@ main = ->{
149
154
  break unless a
150
155
 
151
156
  opts = { '-u' => ->{ build_cache.call ; exit },
152
- '-p' => ->{ (arg = ARGV.shift) ? prog_procs.push(arg) : (help.call ; exit 1) },
153
- '-d' => ->{ (arg = ARGV.shift) ? deps_procs.push(arg) : (help.call ; exit 1) },
157
+ '-p' => ->{ ((arg = ARGV.shift) && !arg[/^-/]) ? prog_procs.push(arg) : (help.call ; exit 1) },
158
+ '-d' => ->{ ((arg = ARGV.shift) && !arg[/^-/]) ? deps_procs.push(arg) : (help.call ; exit 1) },
154
159
  '-j' => ->{ $to_json = true },
155
- '-h' => ->{ help.call ; exit }, }
160
+ '-h' => ->{ help.call ; exit },
161
+ '-v' => ->{ puts VERSION ; exit },}
156
162
 
157
163
  opts.default = ->{ help.call ; exit 1 }
158
164
 
@@ -0,0 +1,22 @@
1
+ 0.0.2:
2
+ - fixed -p and -d argument passing
3
+ - fixed -p and -d printing
4
+
5
+ 0.0.3:
6
+ - added dependency detection for libraries to -d option too
7
+ - fixed set of path libraries when ld.so.conf is not a file
8
+
9
+ 0.0.4:
10
+ - fixed dead links
11
+ - added -v option
12
+ - scan the entire system for libraries instead of
13
+ restricting search to specific paths,
14
+ to support a wide set of linux distros
15
+
16
+ 0.0.5:
17
+ - fixed utf-8 encoding error
18
+ - do not scan only /proc, /sys, and /dev
19
+
20
+ 0.0.6:
21
+ - fixed error crash when building cache
22
+ - added minimal threading when collecting infos
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  # sysdeps common
2
3
  #
3
4
  # Written in 2020 by Francesco Palumbo phranz@subfc.net
@@ -11,8 +12,6 @@
11
12
  # If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
12
13
 
13
14
 
14
- LDCONFPATH = '/etc/ld.so.conf'
15
-
16
15
  DEPMARK = 'NEEDED'.freeze
17
16
  ELF = 'ELF'.freeze
18
17
  SYM = 'symbolic'.freeze
@@ -23,22 +22,37 @@ EMPTY = ''.freeze
23
22
  readlink_absolute = ->(path) {
24
23
  curdir = Dir.getwd
25
24
  Dir.chdir(File.dirname path)
26
- abs = File.absolute_path(File.readlink(File.basename path))
25
+ fp = File.readlink(File.basename path)
26
+ abs = File.exist?(fp) ? File.absolute_path(fp) : nil
27
27
  Dir.chdir curdir
28
28
  abs }
29
29
 
30
30
 
31
- get_syslibs = ->(paths) {
32
- ldpaths = (File.read(LDCONFPATH).split + paths).uniq.join ' '
31
+ get_syslibs = ->(excluded) {
33
32
  sopat = /\.so\.?/
34
33
 
35
- %x(find #{ldpaths} \\( -type f -o -type l \\) 2>/dev/null)
36
- .split
37
- .select { |l|
38
- l[sopat] }
34
+ dirs = (Dir.each_child('/')
35
+ .map { |c| '/' + c }
36
+ .select { |c| File.directory?(c) } - excluded)
37
+ .join ' '
38
+
39
+ res = %x(find #{dirs} \\( -type f -o -type l \\) 2>/dev/null)
40
+
41
+ unless res.valid_encoding?
42
+ res.encode("UTF-8", :invalid=>:replace, :replace=>"?")
43
+ end
44
+
45
+ res .split
46
+ .select { |l| l[sopat] && File.exist?(l) }
39
47
  .map { |l|
40
- File.ftype(l) == LINK ? [l, readlink_absolute(l)] : l }
41
- .flatten }
48
+ if File.ftype(l) == LINK
49
+ fp = readlink_absolute(l)
50
+ fp ? [l, fp] : nil
51
+ else
52
+ l
53
+ end }
54
+ .flatten
55
+ .select { |l| l }}
42
56
 
43
57
 
44
58
  get_program_dependencies = ->(prg) {
@@ -51,10 +65,11 @@ get_program_dependencies = ->(prg) {
51
65
 
52
66
  prgpath = readlink_absolute(prgpath) if File.ftype(prgpath) == LINK
53
67
 
68
+ return nil unless prgpath
54
69
  return nil if %x(file #{prgpath}).split[1] != ELF
55
70
 
56
71
  deppat = /\s+#{DEPMARK}\s+/
57
- %x(objdump -p #{prgpath})
72
+ %x(objdump -p #{prgpath} 2>/dev/null)
58
73
  .split("\n")
59
74
  .select { |r| r.include? DEPMARK }
60
75
  .map { |r| r.gsub(deppat, EMPTY) }}
@@ -65,12 +80,12 @@ get_programs_dependencies = ->() {
65
80
  deppat = /\s+#{DEPMARK}\s+/
66
81
  paths = ENV['PATH'].split(':').join(' ')
67
82
 
68
- IO.popen("find #{paths} -type f -executable") { |find_io|
83
+ IO.popen("find #{paths} -type f -executable 2>/dev/null") { |find_io|
69
84
  find_io.each_with_object({}) { |l, o|
70
85
  next if %x{file #{l}}.split[1] != ELF
71
86
 
72
87
  o[l.chomp] =
73
- %x{objdump -p #{l}}
88
+ %x{objdump -p #{l} 2>/dev/null}
74
89
  .split("\n")
75
90
  .select { |r| r.include? DEPMARK }
76
91
  .map { |r| r.gsub(deppat, EMPTY) }}}}
@@ -82,10 +97,11 @@ get_libraries_dependencies = ->(syslibs) {
82
97
  syslibs.each_with_object({}) { |sl, o|
83
98
  sl = readlink_absolute(sl) if File.ftype(sl) == LINK
84
99
 
100
+ next unless sl
85
101
  next if %x{file #{sl}}.split[1] != ELF
86
102
 
87
103
  o[sl.chomp] =
88
- %x{objdump -p #{sl}}
104
+ %x{objdump -p #{sl} 2>/dev/null}
89
105
  .split("\n")
90
106
  .select { |r| r.include? DEPMARK }
91
107
  .map { |r| r.gsub(deppat, EMPTY) }}}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sysdeps
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Francesco Palumbo
@@ -18,10 +18,12 @@ extensions: []
18
18
  extra_rdoc_files:
19
19
  - README
20
20
  - COPYING
21
+ - changelog
21
22
  files:
22
23
  - COPYING
23
24
  - README
24
25
  - bin/sysdeps
26
+ - changelog
25
27
  - lib/sysdeps.rb
26
28
  homepage: https://gitlab.com/phranz/sysdeps
27
29
  licenses: