sys-admin 1.6.2 → 1.6.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cc10ad595e0df60b19272734c766f8c4dfd28a34
4
- data.tar.gz: f12fb6920c06080d493579d2390a5ae84adbae68
3
+ metadata.gz: 269ba9323aaf5a4925fc94d9c0f5d085ff9d5d2c
4
+ data.tar.gz: b4a6312be3304b7aa12a3e0444230235a9df99ef
5
5
  SHA512:
6
- metadata.gz: 61dbfb21ccdae123b1411f8ad5288b6a6f681247bce7fa652861c0504388e9b7a3a6d756d2dda106236980f508164199da98cffc0ff7fb53ca4494969063a837
7
- data.tar.gz: e09a0b8607bcf2812366a9ba1409bc62a4c6b5a94e68efe0b91fdaf5e6a53e4d695733dac416eb4ca760ba48ebfc5ddccaebc55ddf6d998fd7808ae13a18d624
6
+ metadata.gz: fa2f68ca7a992a8dda0821f76c583eb9abeae941f8446f60368185e1860ee640353a9ccbe5f7f02927e04755220a7f65ad4d18f824866b99b48d972398dfe97c
7
+ data.tar.gz: 25f88dee1694e2e669a1952973c0747f5bc820d396f47b751ff89c630a41719af5c0cb73c5e8cd41929506656868516d541381a8162079a4fb380ce933b578d5
data/CHANGES CHANGED
@@ -1,3 +1,7 @@
1
+ == 1.6.3 - 8-Mar-2014
2
+ * The Admin#get_group method now handles groups with very large numbers
3
+ of members more robustly.
4
+
1
5
  == 1.6.2 - 11-Feb-2014
2
6
  * The User#gid method is now supported on MS Windows. It returns the user's
3
7
  primary group ID.
data/README CHANGED
@@ -131,7 +131,15 @@ Admin::Error < StandardError
131
131
 
132
132
  == Known Bugs
133
133
  None that I'm aware of. If you find any, please log them on the project
134
- page at http://www.rubyforge.org/projects/sysutils.
134
+ page at:
135
+
136
+ https://github.com/djberg96/sys-admin
137
+
138
+ == Contributions
139
+ Although this library is free, please consider having your company
140
+ setup a gittip if used by your company professionally.
141
+
142
+ http://www.gittip.com/djberg96/
135
143
 
136
144
  == License
137
145
  Artistic 2.0
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ require 'rake/clean'
3
3
  require 'rake/testtask'
4
4
  require 'rbconfig'
5
5
 
6
- CLEAN.include("**/*.gem", "**/*.rbx", "**/*.rbc")
6
+ CLEAN.include("**/*.gem", "**/*.rbx", "**/*.rbc", "ruby.core")
7
7
 
8
8
  namespace :gem do
9
9
  desc "Create the sys-uname gem"
data/lib/bsd/sys/admin.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'sys/admin/custom'
2
2
  require 'sys/admin/common'
3
+ require 'rbconfig'
3
4
 
4
5
  # The BSD specific code.
5
6
 
@@ -7,6 +8,9 @@ module Sys
7
8
  class Admin
8
9
  private
9
10
 
11
+ # :no-doc:
12
+ BUF_MAX = 65536 # Max buffer for retry
13
+
10
14
  # I'm making some aliases here to prevent potential conflicts
11
15
  attach_function :open_c, :open, [:string, :int], :int
12
16
  attach_function :pread_c, :pread, [:int, :pointer, :size_t, :off_t], :size_t
@@ -24,18 +28,24 @@ module Sys
24
28
 
25
29
  # struct passwd from /usr/include/pwd.h
26
30
  class PasswdStruct < FFI::Struct
27
- layout(
31
+ fields = [
28
32
  :pw_name, :string,
29
33
  :pw_passwd, :string,
30
- :pw_uid, :uint,
31
- :pw_gid, :uint,
32
- :pw_change, :ulong,
34
+ :pw_uid, :uid_t,
35
+ :pw_gid, :gid_t,
36
+ :pw_change, :time_t,
33
37
  :pw_class, :string,
34
38
  :pw_gecos, :string,
35
39
  :pw_dir, :string,
36
40
  :pw_shell, :string,
37
- :pw_expire, :ulong
38
- )
41
+ :pw_expire, :time_t
42
+ ]
43
+
44
+ if RbConfig::CONFIG['host_os'] =~ /freebsd/i
45
+ fields.push(:pw_fields, :int)
46
+ end
47
+
48
+ layout(*fields)
39
49
  end
40
50
 
41
51
  # struct group from /usr/include/grp.h
@@ -113,24 +123,31 @@ module Sys
113
123
  # Sys::Admin.get_group(101)
114
124
  #
115
125
  def self.get_group(gid)
116
- buf = FFI::MemoryPointer.new(:char, 1024)
126
+ size = 1024
127
+ buf = FFI::MemoryPointer.new(:char, size)
117
128
  pbuf = FFI::MemoryPointer.new(PasswdStruct)
118
129
  temp = GroupStruct.new
119
130
 
120
- if gid.is_a?(String)
121
- if getgrnam_r(gid, temp, buf, buf.size, pbuf) != 0
122
- raise Error, "getgrnam_r function failed: " + strerror(FFI.errno)
123
- end
124
- else
125
- if getgrgid_r(gid, temp, buf, buf.size, pbuf) != 0
126
- raise Error, "getgrgid_r function failed: " + strerror(FFI.errno)
131
+ begin
132
+ if gid.is_a?(String)
133
+ val = getgrnam_r(gid, temp, buf, buf.size, pbuf)
134
+ fun = 'getgrnam_r'
135
+ else
136
+ val = getgrgid_r(gid, temp, buf, buf.size, pbuf)
137
+ fun = 'getgrgid_r'
127
138
  end
139
+ raise SystemCallError.new(fun, val) if val != 0
140
+ rescue Errno::ERANGE
141
+ size += 1024
142
+ raise if size > BUF_MAX
143
+ buf = FFI::MemoryPointer.new(:char, size)
144
+ retry
128
145
  end
129
146
 
130
147
  ptr = pbuf.read_pointer
131
148
 
132
149
  if ptr.null?
133
- raise Error, "no group found for #{gid}"
150
+ raise Error, "no group found for '#{gid}'"
134
151
  end
135
152
 
136
153
  grp = GroupStruct.new(ptr)
@@ -7,6 +7,9 @@ module Sys
7
7
  class Admin
8
8
  private
9
9
 
10
+ # :no-doc:
11
+ BUF_MAX = 65536 # Max buf size for retry.
12
+
10
13
  attach_function :getlogin_r, [:pointer, :int], :int
11
14
  attach_function :getpwnam_r, [:string, :pointer, :pointer, :size_t, :pointer], :int
12
15
  attach_function :getpwuid_r, [:long, :pointer, :pointer, :size_t, :pointer], :int
@@ -109,24 +112,31 @@ module Sys
109
112
  # Sys::Admin.get_group(101)
110
113
  #
111
114
  def self.get_group(gid)
112
- buf = FFI::MemoryPointer.new(:char, 1024)
115
+ size = 1024
116
+ buf = FFI::MemoryPointer.new(:char, size)
113
117
  pbuf = FFI::MemoryPointer.new(PasswdStruct)
114
118
  temp = GroupStruct.new
115
119
 
116
- if gid.is_a?(String)
117
- if getgrnam_r(gid, temp, buf, buf.size, pbuf) != 0
118
- raise Error, "getgrnam_r function failed: " + strerror(FFI.errno)
119
- end
120
- else
121
- if getgrgid_r(gid, temp, buf, buf.size, pbuf) != 0
122
- raise Error, "getgrgid_r function failed: " + strerror(FFI.errno)
120
+ begin
121
+ if gid.is_a?(String)
122
+ val = getgrnam_r(gid, temp, buf, buf.size, pbuf)
123
+ fun = 'getgrnam_r'
124
+ else
125
+ val = getgrgid_r(gid, temp, buf, buf.size, pbuf)
126
+ fun = 'getgrgid_r'
123
127
  end
128
+ raise SystemCallError.new(fun, val) if val != 0
129
+ rescue Errno::ERANGE
130
+ size += 1024
131
+ raise if size > BUF_MAX
132
+ buf = FFI::MemoryPointer.new(:char, size)
133
+ retry
124
134
  end
125
135
 
126
136
  ptr = pbuf.read_pointer
127
137
 
128
138
  if ptr.null?
129
- raise Error, "no group found for #{gid}"
139
+ raise Error, "no group found for '#{gid}'"
130
140
  end
131
141
 
132
142
  grp = GroupStruct.new(ptr)
@@ -7,6 +7,9 @@ module Sys
7
7
  class Admin
8
8
  private
9
9
 
10
+ # :no-doc:
11
+ BUF_MAX = 65536 # Absolute max buffer size for retry attempts.
12
+
10
13
  # I'm making some aliases here to prevent potential conflicts
11
14
  attach_function :open_c, :open, [:string, :int], :int
12
15
  attach_function :pread_c, :pread, [:int, :pointer, :size_t, :off_t], :size_t
@@ -110,26 +113,37 @@ module Sys
110
113
  #
111
114
  # Sys::Admin.get_group('admin')
112
115
  # Sys::Admin.get_group(101)
116
+ #--
117
+ # For groups with a large number of members we retry, allocating another
118
+ # 1k on each retry attempt, up to a maximum of 64k, which ought to be way
119
+ # more than you'll ever need.
113
120
  #
114
121
  def self.get_group(gid)
115
- buf = FFI::MemoryPointer.new(:char, 1024)
122
+ size = 1024
123
+ buf = FFI::MemoryPointer.new(:char, size)
116
124
  pbuf = FFI::MemoryPointer.new(PasswdStruct)
117
125
  temp = GroupStruct.new
118
126
 
119
- if gid.is_a?(String)
120
- if getgrnam_r(gid, temp, buf, buf.size, pbuf) != 0
121
- raise Error, "getgrnam_r function failed: " + strerror(FFI.errno)
122
- end
123
- else
124
- if getgrgid_r(gid, temp, buf, buf.size, pbuf) != 0
125
- raise Error, "getgrgid_r function failed: " + strerror(FFI.errno)
127
+ begin
128
+ if gid.is_a?(String)
129
+ val = getgrnam_r(gid, temp, buf, buf.size, pbuf)
130
+ fun = 'getgrnam_r'
131
+ else
132
+ val = getgrgid_r(gid, temp, buf, buf.size, pbuf)
133
+ fun = 'getgrgid_r'
126
134
  end
135
+ raise SystemCallError.new(fun, val) if val != 0
136
+ rescue Errno::ERANGE # Large groups
137
+ size += 1024
138
+ raise if size > BUF_MAX
139
+ buf = FFI::MemoryPointer.new(:char, size)
140
+ retry
127
141
  end
128
142
 
129
143
  ptr = pbuf.read_pointer
130
144
 
131
145
  if ptr.null?
132
- raise Error, "no group found for #{gid}"
146
+ raise Error, "no group found for '#{gid}'"
133
147
  end
134
148
 
135
149
  grp = GroupStruct.new(ptr)
@@ -7,6 +7,9 @@ module Sys
7
7
  class Admin
8
8
  private
9
9
 
10
+ # :no-doc:
11
+ BUF_MAX = 65536 # Max buffer size for retry.
12
+
10
13
  # I'm making some aliases here to prevent potential conflicts
11
14
  attach_function :open_c, :open, [:string, :int], :int
12
15
  attach_function :pread_c, :pread, [:int, :pointer, :size_t, :off_t], :size_t
@@ -109,17 +112,34 @@ module Sys
109
112
  # Sys::Admin.get_group(101)
110
113
  #
111
114
  def self.get_group(gid)
112
- buf = FFI::MemoryPointer.new(:char, 1024)
115
+ size = 1024
116
+ buf = FFI::MemoryPointer.new(:char, size)
113
117
  temp = GroupStruct.new
114
118
 
115
- if gid.is_a?(String)
116
- ptr = getgrnam_r(gid, temp, buf, buf.size)
117
- else
118
- ptr = getgrgid_r(gid, temp, buf, buf.size)
119
- end
119
+ begin
120
+ if gid.is_a?(String)
121
+ ptr = getgrnam_r(gid, temp, buf, buf.size)
122
+ fun = 'getgrnam_r'
123
+ else
124
+ ptr = getgrgid_r(gid, temp, buf, buf.size)
125
+ fun = 'getgrgid_r'
126
+ end
120
127
 
121
- if ptr.null?
122
- raise Error, "getgrnam_r or getgrgid_r function failed: " + strerror(FFI.errno)
128
+ # SunOS distinguishes between a failed function call and a
129
+ # group that isn't found.
130
+
131
+ if ptr.null?
132
+ if FFI.errno > 0
133
+ raise SystemCallError.new(fun, FFI.errno)
134
+ else
135
+ raise Error, "group '#{gid}' not found"
136
+ end
137
+ end
138
+ rescue Errno::ERANGE
139
+ size += 1024
140
+ raise if size > BUF_MAX
141
+ buf = FFI::MemoryPointer.new(:char, size)
142
+ retry
123
143
  end
124
144
 
125
145
  grp = GroupStruct.new(ptr)
@@ -34,7 +34,7 @@ module Sys
34
34
  public
35
35
 
36
36
  # The version of the sys-admin library.
37
- VERSION = '1.6.2'
37
+ VERSION = '1.6.3'
38
38
 
39
39
  # Error typically raised if any of the Sys::Admin methods fail.
40
40
  class Error < StandardError; end
@@ -5,7 +5,6 @@ require 'sys/admin/common'
5
5
 
6
6
  module Sys
7
7
  class Admin
8
-
9
8
  private
10
9
 
11
10
  class PasswdStruct < FFI::Struct
@@ -300,7 +300,7 @@ module Sys
300
300
  extend FFI::Library
301
301
 
302
302
  # The version of the sys-admin library.
303
- VERSION = '1.6.2'
303
+ VERSION = '1.6.3'
304
304
 
305
305
  # This is the error raised in the majority of cases if anything goes wrong
306
306
  # with any of the Sys::Admin methods.
data/sys-admin.gemspec CHANGED
@@ -3,7 +3,7 @@ require 'rubygems'
3
3
 
4
4
  Gem::Specification.new do |spec|
5
5
  spec.name = 'sys-admin'
6
- spec.version = '1.6.2'
6
+ spec.version = '1.6.3'
7
7
  spec.author = 'Daniel J. Berger'
8
8
  spec.license = 'Artistic 2.0'
9
9
  spec.email = 'djberg96@gmail.com'
@@ -14,6 +14,6 @@ end
14
14
 
15
15
  class TC_Sys_Admin_All < Test::Unit::TestCase
16
16
  test "version is set to expected value" do
17
- assert_equal('1.6.2', Sys::Admin::VERSION)
17
+ assert_equal('1.6.3', Sys::Admin::VERSION)
18
18
  end
19
19
  end
metadata CHANGED
@@ -1,55 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sys-admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.2
4
+ version: 1.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel J. Berger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-12 00:00:00.000000000 Z
11
+ date: 2014-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 1.1.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.1.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: test-unit
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: 2.5.0
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: 2.5.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  description: |2
@@ -97,12 +97,12 @@ require_paths:
97
97
  - lib
98
98
  required_ruby_version: !ruby/object:Gem::Requirement
99
99
  requirements:
100
- - - '>='
100
+ - - ">="
101
101
  - !ruby/object:Gem::Version
102
102
  version: '0'
103
103
  required_rubygems_version: !ruby/object:Gem::Requirement
104
104
  requirements:
105
- - - '>='
105
+ - - ">="
106
106
  - !ruby/object:Gem::Version
107
107
  version: '0'
108
108
  requirements: []