sys-admin 1.8.0-universal-mingw32 → 1.8.2-universal-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGES.md +14 -1
- data/MANIFEST.md +4 -3
- data/README.md +7 -0
- data/Rakefile +5 -4
- data/lib/bsd/sys/admin.rb +28 -24
- data/lib/darwin/sys/admin.rb +37 -19
- data/lib/linux/sys/admin.rb +18 -14
- data/lib/sunos/sys/admin.rb +16 -12
- data/lib/sys/admin/common.rb +5 -4
- data/lib/sys/admin/custom.rb +6 -3
- data/lib/sys/admin.rb +7 -1
- data/lib/sys-admin.rb +2 -0
- data/lib/unix/sys/admin.rb +6 -6
- data/lib/windows/sys/admin.rb +77 -81
- data/spec/spec_helper.rb +22 -0
- data/spec/sys_admin_shared.rb +15 -0
- data/spec/sys_admin_unix_spec.rb +59 -56
- data/spec/sys_admin_windows_spec.rb +80 -90
- data/sys-admin.gemspec +11 -7
- data.tar.gz.sig +0 -0
- metadata +36 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0a5f8abb2d51fd89dfaba1749f6ebedc824e53c16f5d19c7a09d8e5964643f6
|
4
|
+
data.tar.gz: b15cbcbdcb14f3c8067f0d445acad1eb4a106a9a0670640b03d04fd45d49ff03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5344588bd21a2d4cbff3e845cf3dd1bff33f1e5e1996f499e874b100d40861c01f5646212bd0e860b48c6e67c458a4664092efd136beea30deef467476289b4e
|
7
|
+
data.tar.gz: 7b8852c72276c2480320f3fe680baf1a1339b8b51f87a4558eb96610288ffebef45a53f247bf6ed129c2de838c32db37ce883d0d59d6a449287b9e26313830a9
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/CHANGES.md
CHANGED
@@ -1,9 +1,22 @@
|
|
1
|
+
## 1.8.2 - 9-Apr-2023
|
2
|
+
* Lots of rubocop related updates.
|
3
|
+
* Refactored specs to use shared specs.
|
4
|
+
* The lastlog key will return nil instead of an empty struct if it can't be read.
|
5
|
+
* Added more information to the gemspec metadata.
|
6
|
+
* The rubocop and rubocop-rspec gems are now development dependencies.
|
7
|
+
|
8
|
+
## 1.8.1 - 25-Sep-2021
|
9
|
+
* The users and get_user methods on Darwin now take an optional :lastlog key
|
10
|
+
that you can set to false in order to significantly speed up those methods
|
11
|
+
at the expense of taking away lastlog information.
|
12
|
+
* Some internal rspec refactoring.
|
13
|
+
|
1
14
|
## 1.8.0 - 26-Aug-2021
|
2
15
|
* Switched from test-unit to rspec, with some tests refactored. The Rakefile
|
3
16
|
and gemspec files were updated accordingly.
|
4
17
|
* The User and Group classes for the Windows implementation are now properly
|
5
18
|
scoped under Sys::Admin instead of just Sys.
|
6
|
-
* Fixed a bug in the get_user and get_group methods on
|
19
|
+
* Fixed a bug in the get_user and get_group methods on Windows where the WQL
|
7
20
|
it generates internally might not be correct.
|
8
21
|
|
9
22
|
## 1.7.6 - 24-Mar-2021
|
data/MANIFEST.md
CHANGED
@@ -15,6 +15,7 @@
|
|
15
15
|
* lib/sunos/sys/admin.rb
|
16
16
|
* lib/sys/admin/common.rb
|
17
17
|
* lib/sys/admin/custom.rb
|
18
|
-
*
|
19
|
-
*
|
20
|
-
*
|
18
|
+
* spec/spec_helper.rb
|
19
|
+
* spec/sys_admin_universal_spec.rb
|
20
|
+
* spec/sys_admin_unix_spec.rb
|
21
|
+
* spec/sys_admin_windows_spec.rb
|
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
[![Ruby](https://github.com/djberg96/sys-admin/actions/workflows/ruby.yml/badge.svg)](https://github.com/djberg96/sys-admin/actions/workflows/ruby.yml)
|
2
|
+
|
1
3
|
## Description
|
2
4
|
The sys-admin library is a unified, cross platform replacement for the Etc module.
|
3
5
|
|
@@ -142,6 +144,11 @@ The underlying implementation is similar to core Ruby's Etc implementation.
|
|
142
144
|
But, in addition to the different interface, I use the re-entrant version
|
143
145
|
of the appropriate functions when available.
|
144
146
|
|
147
|
+
### OSX
|
148
|
+
The slowdown for collecting lastlog information on OSX seems to have gotten
|
149
|
+
progressively worse over time. Do not be surprised by significant slowdowns
|
150
|
+
if you opt to collect it.
|
151
|
+
|
145
152
|
## Future Plans
|
146
153
|
* Make the User and Group objects comparable.
|
147
154
|
* Add ability to add, configure and delete users on Unix platforms.
|
data/Rakefile
CHANGED
@@ -2,11 +2,12 @@ require 'rake'
|
|
2
2
|
require 'rake/clean'
|
3
3
|
require 'rspec/core/rake_task'
|
4
4
|
require 'rbconfig'
|
5
|
+
require 'rubocop/rake_task'
|
5
6
|
|
6
7
|
CLEAN.include("**/*.gem", "**/*.rbx", "**/*.rbc", "ruby.core", "**/*.lock")
|
7
8
|
|
8
9
|
namespace :gem do
|
9
|
-
desc "Create the sys-
|
10
|
+
desc "Create the sys-admin gem"
|
10
11
|
task :create => [:clean] do
|
11
12
|
require 'rubygems/package'
|
12
13
|
spec = Gem::Specification.load('sys-admin.gemspec')
|
@@ -14,7 +15,7 @@ namespace :gem do
|
|
14
15
|
Gem::Package.build(spec)
|
15
16
|
end
|
16
17
|
|
17
|
-
desc "Install the sys-
|
18
|
+
desc "Install the sys-admin gem"
|
18
19
|
task :install => [:create] do
|
19
20
|
file = Dir["*.gem"].first
|
20
21
|
sh "gem install -l #{file}"
|
@@ -23,7 +24,6 @@ end
|
|
23
24
|
|
24
25
|
desc "Run the specs for the sys-admin library"
|
25
26
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
26
|
-
t.pattern = 'spec/sys_admin_unix_spec.rb'
|
27
27
|
case RbConfig::CONFIG['host_os']
|
28
28
|
when /darwin|osx/i
|
29
29
|
t.rspec_opts = '-Ilib/darwin'
|
@@ -35,10 +35,11 @@ RSpec::Core::RakeTask.new(:spec) do |t|
|
|
35
35
|
t.rspec_opts = '-Ilib/bsd'
|
36
36
|
when /windows|win32|mingw|cygwin|dos/i
|
37
37
|
t.rspec_opts = '-Ilib/windows'
|
38
|
-
t.pattern = 'spec/sys_admin_windows_spec.rb'
|
39
38
|
else
|
40
39
|
t.rspec_opts = '-Ilib/unix'
|
41
40
|
end
|
42
41
|
end
|
43
42
|
|
43
|
+
RuboCop::RakeTask.new
|
44
|
+
|
44
45
|
task :default => :spec
|
data/lib/bsd/sys/admin.rb
CHANGED
@@ -1,42 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'sys/admin/custom'
|
2
4
|
require 'sys/admin/common'
|
3
5
|
require 'rbconfig'
|
4
6
|
|
5
7
|
# The BSD specific code.
|
6
8
|
|
9
|
+
# The Sys module serves as a namespace only.
|
7
10
|
module Sys
|
11
|
+
# The Admin class provides a unified, cross platform replacement for the Etc module.
|
8
12
|
class Admin
|
9
13
|
# :no-doc:
|
10
14
|
BUF_MAX = 65536 # Max buffer for retry
|
11
15
|
private_constant :BUF_MAX
|
12
16
|
|
13
17
|
# I'm making some aliases here to prevent potential conflicts
|
14
|
-
attach_function :open_c, :open, [
|
15
|
-
attach_function :pread_c, :pread, [
|
18
|
+
attach_function :open_c, :open, %i[string int], :int
|
19
|
+
attach_function :pread_c, :pread, %i[int pointer size_t off_t], :size_t
|
16
20
|
attach_function :close_c, :close, [:int], :int
|
17
21
|
|
18
|
-
attach_function :getlogin_r, [
|
19
|
-
attach_function :getpwnam_r, [
|
20
|
-
attach_function :getpwuid_r, [
|
21
|
-
attach_function :getgrnam_r, [
|
22
|
-
attach_function :getgrgid_r, [
|
22
|
+
attach_function :getlogin_r, %i[pointer int], :int
|
23
|
+
attach_function :getpwnam_r, %i[string pointer pointer size_t pointer], :int
|
24
|
+
attach_function :getpwuid_r, %i[long pointer pointer size_t pointer], :int
|
25
|
+
attach_function :getgrnam_r, %i[string pointer pointer size_t pointer], :int
|
26
|
+
attach_function :getgrgid_r, %i[long pointer pointer size_t pointer], :int
|
23
27
|
|
24
28
|
private_class_method :getlogin_r, :getpwnam_r, :getpwuid_r, :getgrnam_r, :getgrgid_r
|
25
29
|
private_class_method :open_c, :pread_c, :close_c
|
26
30
|
|
27
31
|
# struct passwd from /usr/include/pwd.h
|
28
32
|
class PasswdStruct < FFI::Struct
|
29
|
-
fields = [
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
33
|
+
fields = %i[
|
34
|
+
pw_name string
|
35
|
+
pw_passwd string
|
36
|
+
pw_uid uid_t
|
37
|
+
pw_gid gid_t
|
38
|
+
pw_change time_t
|
39
|
+
pw_class string
|
40
|
+
pw_gecos string
|
41
|
+
pw_dir string
|
42
|
+
pw_shell string
|
43
|
+
pw_expire time_t
|
40
44
|
]
|
41
45
|
|
42
46
|
if RbConfig::CONFIG['host_os'] =~ /freebsd/i
|
@@ -77,7 +81,7 @@ module Sys
|
|
77
81
|
buf = FFI::MemoryPointer.new(:char, 256)
|
78
82
|
|
79
83
|
if getlogin_r(buf, buf.size) != 0
|
80
|
-
raise Error, "getlogin_r function failed:
|
84
|
+
raise Error, "getlogin_r function failed: #{strerror(FFI.errno)}"
|
81
85
|
end
|
82
86
|
|
83
87
|
buf.read_string
|
@@ -98,11 +102,11 @@ module Sys
|
|
98
102
|
|
99
103
|
if uid.is_a?(String)
|
100
104
|
if getpwnam_r(uid, temp, buf, buf.size, pbuf) != 0
|
101
|
-
raise Error, "getpwnam_r function failed:
|
105
|
+
raise Error, "getpwnam_r function failed: #{strerror(FFI.errno)}"
|
102
106
|
end
|
103
107
|
else
|
104
108
|
if getpwuid_r(uid, temp, buf, buf.size, pbuf) != 0
|
105
|
-
raise Error, "getpwuid_r function failed:
|
109
|
+
raise Error, "getpwuid_r function failed: #{strerror(FFI.errno)}"
|
106
110
|
end
|
107
111
|
end
|
108
112
|
|
@@ -242,13 +246,13 @@ module Sys
|
|
242
246
|
begin
|
243
247
|
fd = open_c(logfile, File::RDONLY)
|
244
248
|
|
245
|
-
if fd
|
249
|
+
if fd >= 0
|
246
250
|
bytes = pread_c(fd, lastlog, lastlog.size, uid * lastlog.size)
|
247
251
|
if bytes < 0
|
248
|
-
raise Error, "pread function failed:
|
252
|
+
raise Error, "pread function failed: #{strerror(FFI.errno)}"
|
249
253
|
end
|
250
254
|
else
|
251
|
-
nil # Ignore, improper permissions
|
255
|
+
lastlog = nil # Ignore, most likely improper permissions
|
252
256
|
end
|
253
257
|
ensure
|
254
258
|
close_c(fd) if fd && fd >= 0
|
data/lib/darwin/sys/admin.rb
CHANGED
@@ -1,20 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'sys/admin/custom'
|
2
4
|
require 'sys/admin/common'
|
3
5
|
|
4
6
|
# The Darwin specific code.
|
5
7
|
|
8
|
+
# The Sys module serves as a namespace only.
|
6
9
|
module Sys
|
10
|
+
# The Admin class provides a unified, cross platform replacement for the Etc module.
|
7
11
|
class Admin
|
8
12
|
# :no-doc:
|
9
13
|
BUF_MAX = 65536 # Max buf size for retry.
|
10
14
|
private_constant :BUF_MAX
|
11
15
|
|
12
|
-
attach_function :getlogin_r, [
|
13
|
-
attach_function :getpwnam_r, [
|
14
|
-
attach_function :getpwuid_r, [
|
15
|
-
attach_function :getgrnam_r, [
|
16
|
-
attach_function :getgrgid_r, [
|
17
|
-
attach_function :getlastlogx, [
|
16
|
+
attach_function :getlogin_r, %i[pointer int], :int
|
17
|
+
attach_function :getpwnam_r, %i[string pointer pointer size_t pointer], :int
|
18
|
+
attach_function :getpwuid_r, %i[long pointer pointer size_t pointer], :int
|
19
|
+
attach_function :getgrnam_r, %i[string pointer pointer size_t pointer], :int
|
20
|
+
attach_function :getgrgid_r, %i[long pointer pointer size_t pointer], :int
|
21
|
+
attach_function :getlastlogx, %i[long pointer], :pointer
|
18
22
|
|
19
23
|
private_class_method :getlogin_r, :getpwnam_r, :getpwuid_r
|
20
24
|
private_class_method :getgrnam_r, :getgrgid_r, :getlastlogx
|
@@ -67,7 +71,7 @@ module Sys
|
|
67
71
|
buf = FFI::MemoryPointer.new(:char, 256)
|
68
72
|
|
69
73
|
if getlogin_r(buf, buf.size) != 0
|
70
|
-
raise Error, "getlogin_r function failed:
|
74
|
+
raise Error, "getlogin_r function failed: #{strerror(FFI.errno)}"
|
71
75
|
end
|
72
76
|
|
73
77
|
buf.read_string
|
@@ -80,19 +84,23 @@ module Sys
|
|
80
84
|
#
|
81
85
|
# Sys::Admin.get_user('joe')
|
82
86
|
# Sys::Admin.get_user(501)
|
87
|
+
# Sys::Admin.get_user('joe', :lastlog => false) # Less info but faster
|
88
|
+
#
|
89
|
+
# Set the :lastlog option to false if you want to ignore lastlog
|
90
|
+
# information and speed this method up considerably.
|
83
91
|
#
|
84
|
-
def self.get_user(uid)
|
92
|
+
def self.get_user(uid, options = {})
|
85
93
|
buf = FFI::MemoryPointer.new(:char, 1024)
|
86
94
|
pbuf = FFI::MemoryPointer.new(PasswdStruct)
|
87
95
|
temp = PasswdStruct.new
|
88
96
|
|
89
97
|
if uid.is_a?(String)
|
90
98
|
if getpwnam_r(uid, temp, buf, buf.size, pbuf) != 0
|
91
|
-
raise Error, "getpwnam_r function failed:
|
99
|
+
raise Error, "getpwnam_r function failed: #{strerror(FFI.errno)}"
|
92
100
|
end
|
93
101
|
else
|
94
102
|
if getpwuid_r(uid, temp, buf, buf.size, pbuf) != 0
|
95
|
-
raise Error, "getpwuid_r function failed:
|
103
|
+
raise Error, "getpwuid_r function failed: #{strerror(FFI.errno)}"
|
96
104
|
end
|
97
105
|
end
|
98
106
|
|
@@ -103,7 +111,7 @@ module Sys
|
|
103
111
|
end
|
104
112
|
|
105
113
|
pwd = PasswdStruct.new(ptr)
|
106
|
-
get_user_from_struct(pwd)
|
114
|
+
get_user_from_struct(pwd, options)
|
107
115
|
end
|
108
116
|
|
109
117
|
# Returns a Group object for the given name or uid. Raises an error
|
@@ -148,11 +156,19 @@ module Sys
|
|
148
156
|
|
149
157
|
# Returns an array of User objects for each user on the system.
|
150
158
|
#
|
159
|
+
# Examples:
|
160
|
+
#
|
161
|
+
# Sys::Admin.users
|
162
|
+
# Sys::Admin.users(:lastlog => false) # Less info but faster
|
163
|
+
#
|
164
|
+
# Note that on Darwin this method can be very slow. If you want to
|
165
|
+
# speed it up considerably by ignoring lastlog information then set
|
166
|
+
# the :lastlog option to false as part of the +options+ hash.
|
151
167
|
#--
|
152
168
|
# This method is somewhat slow on OSX because of the call to get
|
153
169
|
# lastlog information. I'm not sure why.
|
154
170
|
#
|
155
|
-
def self.users
|
171
|
+
def self.users(options = {})
|
156
172
|
users = []
|
157
173
|
|
158
174
|
begin
|
@@ -160,7 +176,7 @@ module Sys
|
|
160
176
|
|
161
177
|
until (ptr = getpwent()).null?
|
162
178
|
pwd = PasswdStruct.new(ptr)
|
163
|
-
users << get_user_from_struct(pwd)
|
179
|
+
users << get_user_from_struct(pwd, options)
|
164
180
|
end
|
165
181
|
ensure
|
166
182
|
endpwent()
|
@@ -201,7 +217,7 @@ module Sys
|
|
201
217
|
private_class_method :get_group_from_struct
|
202
218
|
|
203
219
|
# Takes a UserStruct and converts it to a User object.
|
204
|
-
def self.get_user_from_struct(pwd)
|
220
|
+
def self.get_user_from_struct(pwd, options)
|
205
221
|
user = User.new do |u|
|
206
222
|
u.name = pwd[:pw_name]
|
207
223
|
u.passwd = pwd[:pw_passwd]
|
@@ -215,12 +231,14 @@ module Sys
|
|
215
231
|
u.expire = Time.at(pwd[:pw_expire])
|
216
232
|
end
|
217
233
|
|
218
|
-
|
234
|
+
unless options[:lastlog] == false
|
235
|
+
log = get_lastlog_info(user.uid)
|
219
236
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
237
|
+
if log
|
238
|
+
user.login_time = Time.at(log[:tv_sec])
|
239
|
+
user.login_device = log[:ll_line].to_s
|
240
|
+
user.login_host = log[:ll_host].to_s
|
241
|
+
end
|
224
242
|
end
|
225
243
|
|
226
244
|
user
|
data/lib/linux/sys/admin.rb
CHANGED
@@ -1,25 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'sys/admin/custom'
|
2
4
|
require 'sys/admin/common'
|
3
5
|
|
4
6
|
# The Linux specific code.
|
5
7
|
|
8
|
+
# The Sys module serves as a namespace only.
|
6
9
|
module Sys
|
10
|
+
# The Admin class provides a unified, cross platform replacement for the Etc module.
|
7
11
|
class Admin
|
8
12
|
# :no-doc:
|
9
13
|
BUF_MAX = 65536 # Absolute max buffer size for retry attempts.
|
10
14
|
private_constant :BUF_MAX
|
11
15
|
|
12
16
|
# I'm making some aliases here to prevent potential conflicts
|
13
|
-
attach_function :open_c, :open, [
|
14
|
-
attach_function :pread_c, :pread, [
|
17
|
+
attach_function :open_c, :open, %i[string int], :int
|
18
|
+
attach_function :pread_c, :pread, %i[int pointer size_t off_t], :size_t
|
15
19
|
attach_function :close_c, :close, [:int], :int
|
16
20
|
|
17
|
-
attach_function :getpwnam_r, [
|
18
|
-
attach_function :getpwuid_r, [
|
19
|
-
attach_function :getpwent_r, [
|
20
|
-
attach_function :getgrent_r, [
|
21
|
-
attach_function :getgrnam_r, [
|
22
|
-
attach_function :getgrgid_r, [
|
21
|
+
attach_function :getpwnam_r, %i[string pointer pointer size_t pointer], :int
|
22
|
+
attach_function :getpwuid_r, %i[long pointer pointer size_t pointer], :int
|
23
|
+
attach_function :getpwent_r, %i[pointer pointer size_t pointer], :int
|
24
|
+
attach_function :getgrent_r, %i[pointer pointer size_t pointer], :int
|
25
|
+
attach_function :getgrnam_r, %i[string pointer pointer size_t pointer], :int
|
26
|
+
attach_function :getgrgid_r, %i[long pointer pointer size_t pointer], :int
|
23
27
|
|
24
28
|
private_class_method :getgrent_r, :getgrnam_r, :getgrgid_r
|
25
29
|
private_class_method :open_c, :pread_c, :close_c
|
@@ -83,11 +87,11 @@ module Sys
|
|
83
87
|
|
84
88
|
if uid.is_a?(String)
|
85
89
|
if getpwnam_r(uid, temp, buf, buf.size, pbuf) != 0
|
86
|
-
raise Error, "getpwnam_r function failed:
|
90
|
+
raise Error, "getpwnam_r function failed: #{strerror(FFI.errno)}"
|
87
91
|
end
|
88
92
|
else
|
89
93
|
if getpwuid_r(uid, temp, buf, buf.size, pbuf) != 0
|
90
|
-
raise Error, "getpwuid_r function failed:
|
94
|
+
raise Error, "getpwuid_r function failed: #{strerror(FFI.errno)}"
|
91
95
|
end
|
92
96
|
end
|
93
97
|
|
@@ -239,7 +243,7 @@ module Sys
|
|
239
243
|
|
240
244
|
private_class_method :get_user_from_struct
|
241
245
|
|
242
|
-
#
|
246
|
+
# NOTE: It seems that Linux, or at least Ubuntu, does not track logins
|
243
247
|
# via GDM (Gnome Display Manager) for some reason, so this may not return
|
244
248
|
# anything useful.
|
245
249
|
#
|
@@ -252,13 +256,13 @@ module Sys
|
|
252
256
|
begin
|
253
257
|
fd = open_c(logfile, File::RDONLY)
|
254
258
|
|
255
|
-
if fd
|
259
|
+
if fd >= 0
|
256
260
|
bytes = pread_c(fd, lastlog, lastlog.size, uid * lastlog.size)
|
257
261
|
if bytes < 0
|
258
|
-
raise Error, "pread function failed:
|
262
|
+
raise Error, "pread function failed: #{strerror(FFI.errno)}"
|
259
263
|
end
|
260
264
|
else
|
261
|
-
nil # Ignore, improper permissions
|
265
|
+
lastlog = nil # Ignore, most likely improper permissions
|
262
266
|
end
|
263
267
|
ensure
|
264
268
|
close_c(fd) if fd && fd >= 0
|
data/lib/sunos/sys/admin.rb
CHANGED
@@ -1,26 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'sys/admin/custom'
|
2
4
|
require 'sys/admin/common'
|
3
5
|
|
4
6
|
# The Solaris specific code.
|
5
7
|
|
8
|
+
# The Sys module serves as a namespace only.
|
6
9
|
module Sys
|
10
|
+
# The Admin class provides a unified, cross platform replacement for the Etc module.
|
7
11
|
class Admin
|
8
12
|
# :no-doc:
|
9
13
|
BUF_MAX = 65536 # Max buffer size for retry.
|
10
14
|
private_constant :BUF_MAX
|
11
15
|
|
12
16
|
# I'm making some aliases here to prevent potential conflicts
|
13
|
-
attach_function :open_c, :open, [
|
14
|
-
attach_function :pread_c, :pread, [
|
17
|
+
attach_function :open_c, :open, %i[string int], :int
|
18
|
+
attach_function :pread_c, :pread, %i[int pointer size_t off_t], :size_t
|
15
19
|
attach_function :close_c, :close, [:int], :int
|
16
20
|
|
17
|
-
attach_function :getlogin_r, [
|
18
|
-
attach_function :getpwnam_r, [
|
19
|
-
attach_function :getpwuid_r, [
|
20
|
-
attach_function :getpwent_r, [
|
21
|
-
attach_function :getgrent_r, [
|
22
|
-
attach_function :getgrnam_r, [
|
23
|
-
attach_function :getgrgid_r, [
|
21
|
+
attach_function :getlogin_r, %i[pointer size_t], :pointer
|
22
|
+
attach_function :getpwnam_r, %i[string pointer pointer size_t], :pointer
|
23
|
+
attach_function :getpwuid_r, %i[long pointer pointer size_t], :pointer
|
24
|
+
attach_function :getpwent_r, %i[pointer pointer int], :pointer
|
25
|
+
attach_function :getgrent_r, %i[pointer pointer int], :pointer
|
26
|
+
attach_function :getgrnam_r, %i[string pointer pointer int], :pointer
|
27
|
+
attach_function :getgrgid_r, %i[long pointer pointer int], :pointer
|
24
28
|
|
25
29
|
private_class_method :getlogin_r, :getpwnam_r, :getpwuid_r, :getpwent_r
|
26
30
|
private_class_method :getgrent_r, :getgrnam_r, :getgrgid_r
|
@@ -74,7 +78,7 @@ module Sys
|
|
74
78
|
ptr = getlogin_r(buf, buf.size)
|
75
79
|
|
76
80
|
if ptr.null?
|
77
|
-
raise Error, "getlogin_r function failed:
|
81
|
+
raise Error, "getlogin_r function failed: #{strerror(FFI.errno)}"
|
78
82
|
end
|
79
83
|
|
80
84
|
buf.read_string
|
@@ -99,7 +103,7 @@ module Sys
|
|
99
103
|
end
|
100
104
|
|
101
105
|
if ptr.null?
|
102
|
-
raise Error, "getpwnam_r or getpwuid_r function failed:
|
106
|
+
raise Error, "getpwnam_r or getpwuid_r function failed: #{strerror(FFI.errno)}"
|
103
107
|
end
|
104
108
|
|
105
109
|
pwd = PasswdStruct.new(ptr)
|
@@ -251,7 +255,7 @@ module Sys
|
|
251
255
|
if fd != -1
|
252
256
|
bytes = pread_c(fd, lastlog, lastlog.size, uid * lastlog.size)
|
253
257
|
if bytes < 0
|
254
|
-
raise Error, "pread function failed:
|
258
|
+
raise Error, "pread function failed: #{strerror(FFI.errno)}"
|
255
259
|
end
|
256
260
|
else
|
257
261
|
nil # Ignore, improper permissions
|
data/lib/sys/admin/common.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'ffi'
|
2
4
|
|
3
5
|
# The Sys module serves as a namespace only.
|
4
6
|
module Sys
|
5
|
-
|
6
7
|
# The Admin class provides a unified, cross platform replacement
|
7
8
|
# for the Etc module.
|
8
9
|
class Admin
|
@@ -99,9 +100,9 @@ module Sys
|
|
99
100
|
def groups
|
100
101
|
array = []
|
101
102
|
|
102
|
-
Sys::Admin.groups.each
|
103
|
-
array << grp.name if grp.members.include?(
|
104
|
-
|
103
|
+
Sys::Admin.groups.each do |grp|
|
104
|
+
array << grp.name if grp.members.include?(name)
|
105
|
+
end
|
105
106
|
|
106
107
|
array
|
107
108
|
end
|
data/lib/sys/admin/custom.rb
CHANGED
@@ -1,14 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'ffi'
|
2
4
|
|
5
|
+
# Re-open the FFI::Pointer class to add a custom method.
|
3
6
|
class FFI::Pointer
|
4
7
|
def read_array_of_string
|
5
8
|
elements = []
|
6
9
|
|
7
10
|
loc = self
|
8
11
|
|
9
|
-
until (
|
10
|
-
|
11
|
-
|
12
|
+
until (element = loc.read_pointer).null?
|
13
|
+
elements << element.read_string
|
14
|
+
loc += FFI::Type::POINTER.size
|
12
15
|
end
|
13
16
|
|
14
17
|
elements
|
data/lib/sys/admin.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# The Sys modules serves as a namespace only.
|
1
4
|
module Sys
|
5
|
+
# The Admin class provides a unified, cross platform replacement for the Etc module.
|
2
6
|
class Admin
|
3
7
|
# The version of the sys-admin library.
|
4
|
-
VERSION = '1.8.
|
8
|
+
VERSION = '1.8.2'
|
9
|
+
|
10
|
+
private_class_method :new
|
5
11
|
end
|
6
12
|
end
|
7
13
|
|
data/lib/sys-admin.rb
CHANGED
data/lib/unix/sys/admin.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'sys/admin/custom'
|
2
4
|
require 'sys/admin/common'
|
3
5
|
|
4
6
|
# Code used as a fallback for UNIX platforms.
|
5
7
|
|
8
|
+
# The Sys module serves as a namespace only.
|
6
9
|
module Sys
|
10
|
+
# The Admin class provides a unified, cross platform replacement for the Etc module.
|
7
11
|
class Admin
|
8
12
|
class PasswdStruct < FFI::Struct
|
9
13
|
layout(
|
@@ -55,7 +59,7 @@ module Sys
|
|
55
59
|
raise Error, "no user found for: #{uid}"
|
56
60
|
end
|
57
61
|
|
58
|
-
|
62
|
+
User.new do |u|
|
59
63
|
u.name = pwd[:pw_name]
|
60
64
|
u.passwd = pwd[:pw_passwd]
|
61
65
|
u.uid = pwd[:pw_uid]
|
@@ -64,8 +68,6 @@ module Sys
|
|
64
68
|
u.dir = pwd[:pw_dir]
|
65
69
|
u.shell = pwd[:pw_shell]
|
66
70
|
end
|
67
|
-
|
68
|
-
user
|
69
71
|
end
|
70
72
|
|
71
73
|
# Returns a Group object for the given name or uid. Raises an error
|
@@ -147,7 +149,7 @@ module Sys
|
|
147
149
|
|
148
150
|
# Takes a UserStruct and converts it to a User object.
|
149
151
|
def self.get_user_from_struct(pwd)
|
150
|
-
|
152
|
+
User.new do |u|
|
151
153
|
u.name = pwd[:pw_name]
|
152
154
|
u.passwd = pwd[:pw_passwd]
|
153
155
|
u.uid = pwd[:pw_uid]
|
@@ -156,8 +158,6 @@ module Sys
|
|
156
158
|
u.dir = pwd[:pw_dir]
|
157
159
|
u.shell = pwd[:pw_shell]
|
158
160
|
end
|
159
|
-
|
160
|
-
user
|
161
161
|
end
|
162
162
|
|
163
163
|
private_class_method :get_user_from_struct
|