sys-admin 1.4.5 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,8 +1,15 @@
1
- == 1.4.5 - 1-Mar-2009
1
+ == 1.5.0 - 29-Mar-2009
2
+ * INTERFACE CHANGE (WINDOWS ONLY): The interface for MS Windows has undergone
3
+ a radical change. Most methods now accept a hash of options that are
4
+ passed directly to the underlying WMI class. Please see the documentation
5
+ for details.
6
+ * Now works on various BSD flavors.
2
7
  * Added the User#groups method. This returns an array of groups that the
3
8
  user belongs to. Suggestion inspired by Gonzalo Garramuno.
4
- * Changed User#class to User#access_class to avoid conflicts with the
5
- Ruby core Object method.
9
+ * Added the Group#members method. The returns an array of users that the
10
+ group contains.
11
+ * Changed User#class to User#access_class for UNIX flavors to avoid
12
+ conflicts with the Ruby core Object method.
6
13
  * Added more tests and renamed the test files.
7
14
  * Removed an unnecessary function call where a platform might try to
8
15
  get lastlog information even if the lastlog.h or utmp.h headers couldn't
data/README CHANGED
@@ -39,39 +39,33 @@
39
39
  Admin.get_login
40
40
  Returns the user name (only) of the current login.
41
41
 
42
- Admin.get_user(name, host=localhost)
43
- Admin.get_user(uid, host=localhost, local=true)
44
- Returns a User object based on +name+ or +uid+.
42
+ Admin.get_user(name, options = {})
43
+ Admin.get_user(uid, options = {})
44
+ Returns a User object based on +name+ or +uid+. The +options+ hash is
45
+ for MS Windows only, and allows you to restrict the search based on the
46
+ options you provide, e.g. 'domain' or 'localaccount'.
45
47
 
46
- Windows only: you may specify a host from which information is retrieved.
47
- The default is the local machine. You may also specify whether to
48
- retrieve a local or global account. The default is local.
49
-
50
- Admin.get_group(name, host=localhost, local=true)
51
- Admin.get_group(gid, host=localhost, local=true)
52
- Returns a Group object based on +name+ or +uid+.
53
-
54
- Windows only: you may specify a host from which information is retrieved.
55
- The default is the local machine. You can retrieve either a global or
56
- local group, depending on the value of the +local+ argument.
57
-
58
- Admin.groups(host=localhost, local=true)
59
- Admin.groups(host=localhost, local=true){ |group| ... }
48
+ Admin.get_group(name, options = {})
49
+ Admin.get_group(gid, options = {})
50
+ Returns a Group object based on +name+ or +uid+. The +options+ hash is
51
+ for MS Windows only, and allows you to restrict the search based on the
52
+ options you provide, e.g. 'domain' or 'localaccount'.
53
+
54
+ Admin.groups(options = {})
55
+ Admin.groups(options = {}){ |group| ... }
60
56
  In block form, yields a Group object for each user on the system. In
61
57
  non-block form, returns an Array of Group objects.
62
58
 
63
- Windows only: you may specify a host from which information is retrieved.
64
- The default is the local machine. You can retrieve either a global or
65
- local group, depending on the value of the +local+ argument.
59
+ The +options+ hash is for MS Windows only, and allows you to restrict the
60
+ search based on the options you provide, e.g. 'domain' or 'localaccount'.
66
61
 
67
- Admin.users(host=localhost, local=true)
68
- Admin.users(host=localhost, local=true){ |user| ... }
62
+ Admin.users(options = {})
63
+ Admin.users(options = {}){ |user| ... }
69
64
  In block form, yields a User object for each user on the system. In
70
65
  non-block form, returns an Array of User objects.
71
66
 
72
- Windows only: you may specify a host from which information is retrieved.
73
- The default is the local machine. You can retrieve either a global or
74
- local group, depending on the value of the +local+ argument.
67
+ The +options+ hash is for MS Windows only, and allows you to restrict the
68
+ search based on the options you provide, e.g. 'domain' or 'localaccount'.
75
69
 
76
70
  == User class
77
71
  === User (Windows)
@@ -143,34 +137,14 @@ Admin::Error < StandardError
143
137
  information. This means that the WMI service must be running on the
144
138
  target machine in order to work (which it is, by default).
145
139
 
146
- Note that, by default, local user and group information is retrieved
147
- instead of global. You probably do NOT want to iterate over global users
148
- or groups because there can be quite a few on your domain.
149
-
150
140
  === UNIX
151
141
  The underlying implementation is similar to core Ruby's Etc implementation.
152
142
  But, in addition to the different interface, I use the re-entrant version
153
143
  of the appropriate functions when available.
154
144
 
155
145
  == Future Plans
156
- Add the following methods for UNIX:
157
-
158
- * Admin.add_local_user
159
- * Admin.config_local_user
160
- * Admin.delete_local_user
161
- * Admin.add_global_user
162
- * Admin.config_global_user
163
- * Admin.delete_global_user
164
-
165
- * Admin.add_local_group
166
- * Admin.config_local_group
167
- * Admin.delete_local_group
168
- * Admin.add_global_group
169
- * Admin.config_global_group
170
- * Admin.delete_global_group
171
-
172
146
  Make the User and Group objects comparable.
173
- Support BSD.
147
+ Add ability to add, configure and delete users on Unix platforms.
174
148
 
175
149
  == Known Bugs
176
150
  None that I'm aware of. If you find any, please log them on the project
@@ -48,7 +48,7 @@ else
48
48
  end
49
49
 
50
50
  $CFLAGS += " -D_POSIX_PTHREAD_SEMANTICS"
51
- if RUBY_PLATFORM.match("linux")
51
+ if RUBY_PLATFORM =~ /linux|bsd/i
52
52
  $CFLAGS += " -D_GNU_SOURCE -D_REENTRANT"
53
53
  end
54
54
  end
@@ -159,7 +159,11 @@ static VALUE admin_groups_body(VALUE klass){
159
159
  char buf[GROUP_BUF_SIZE];
160
160
  #ifdef _GNU_SOURCE
161
161
  struct group* grp_p;
162
+
162
163
  while(!getgrent_r(&grp, buf, GROUP_BUF_SIZE, &grp_p)){
164
+ if(grp_p == NULL)
165
+ break;
166
+
163
167
  if(rb_block_given_p())
164
168
  rb_yield(get_group(grp_p));
165
169
  else
@@ -221,7 +225,11 @@ static VALUE admin_users_body(VALUE klass){
221
225
 
222
226
  #ifdef _GNU_SOURCE
223
227
  struct passwd* pwd_p;
228
+
224
229
  while(!getpwent_r(&pwd, buf, USER_BUF_SIZE, &pwd_p)){
230
+ if(pwd_p == NULL)
231
+ break;
232
+
225
233
  if(rb_block_given_p())
226
234
  rb_yield(get_user(pwd_p));
227
235
  else
@@ -396,6 +404,6 @@ void Init_admin(){
396
404
 
397
405
  /* Constants */
398
406
 
399
- /* 1.4.5: The version of this library */
407
+ /* 1.5.0: The version of this library */
400
408
  rb_define_const(cAdmin, "VERSION", rb_str_new2(SYS_ADMIN_VERSION));
401
409
  }
@@ -8,7 +8,15 @@
8
8
  #include <errno.h>
9
9
  #include <string.h>
10
10
 
11
- #define SYS_ADMIN_VERSION "1.4.5"
11
+ #define SYS_ADMIN_VERSION "1.5.0"
12
+
13
+ #if defined(__MACH__) || defined(__APPLE__)
14
+ #define __BSD__
15
+ #endif
16
+
17
+ #if defined(__FreeBSD__) || defined (__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
18
+ #define __BSD__
19
+ #endif
12
20
 
13
21
  #ifdef HAVE_LASTLOG_H
14
22
  #include <lastlog.h>
@@ -20,8 +28,8 @@
20
28
  #define _POSIX_LOGIN_NAME_MAX 9
21
29
  #endif
22
30
 
23
- /* OS X returns -1 on this for some reason, so check for it */
24
- #if defined(__MACH__) || defined(__APPLE__)
31
+ // BSD platforms are problematic with explicit inclusion of unistd.h
32
+ #if defined(__BSD__)
25
33
  #define USER_BUF_SIZE 1024
26
34
  #else
27
35
  #ifdef _SC_GETPW_R_SIZE_MAX
@@ -31,8 +39,8 @@
31
39
  #endif
32
40
  #endif
33
41
 
34
- /* OS X returns -1 on this for some reason, so check for it */
35
- #if defined(__MACH__) || defined(__APPLE__)
42
+ // BSD platforms are problematic with explicit inclusion of unistd.h
43
+ #if defined(__BSD__)
36
44
  #define GROUP_BUF_SIZE 7296
37
45
  #else
38
46
  #ifdef _SC_GETGR_R_SIZE_MAX
@@ -61,7 +69,7 @@ VALUE cUser, cGroup, cAdminError;
61
69
  * Helper function that returns a User object based on user ID.
62
70
  */
63
71
  static VALUE get_user_by_num(VALUE v_uid){
64
- VALUE v_user;
72
+ volatile VALUE v_user;
65
73
  uid_t uid = NUM2INT(v_uid);
66
74
 
67
75
  #ifdef HAVE_GETPWUID_R
@@ -95,7 +103,7 @@ static VALUE get_user_by_num(VALUE v_uid){
95
103
  * Helper function that returns a User object based on name.
96
104
  */
97
105
  static VALUE get_user_by_name(VALUE v_name){
98
- VALUE v_user;
106
+ volatile VALUE v_user;
99
107
  SafeStringValue(v_name);
100
108
 
101
109
  #ifdef HAVE_GETPWNAM_R
@@ -129,7 +137,7 @@ static VALUE get_user_by_name(VALUE v_name){
129
137
  * Helper function that returns a Group object based on group ID.
130
138
  */
131
139
  static VALUE get_group_by_num(VALUE v_gid){
132
- VALUE v_group;
140
+ volatile VALUE v_group;
133
141
  gid_t gid = NUM2INT(v_gid);
134
142
 
135
143
  #ifdef HAVE_GETGRGID_R
@@ -163,7 +171,7 @@ static VALUE get_group_by_num(VALUE v_gid){
163
171
  * Helper function that returns a Group object based on group name.
164
172
  */
165
173
  static VALUE get_group_by_name(VALUE v_name){
166
- VALUE v_group = Qnil;
174
+ volatile VALUE v_group = Qnil;
167
175
  SafeStringValue(v_name);
168
176
  #ifdef HAVE_GETGRNAM_R
169
177
  char buf[GROUP_BUF_SIZE];
@@ -16,6 +16,6 @@ end
16
16
 
17
17
  class TC_Sys_Admin_All < Test::Unit::TestCase
18
18
  def test_version
19
- assert_equal('1.4.5', Sys::Admin::VERSION)
19
+ assert_equal('1.5.0', Sys::Admin::VERSION)
20
20
  end
21
21
  end
@@ -22,117 +22,160 @@ class TC_Sys_Admin_Win32 < Test::Unit::TestCase
22
22
 
23
23
  def setup
24
24
  @user = User.new
25
- @user_name = 'guest'
25
+ @user_name = 'Guest'
26
26
  @user_id = 501 # best guess, may fail
27
27
  @group = Group.new
28
- @group_name = 'guests'
28
+ @group_name = 'Guests'
29
29
  @group_id = 546 # best guess, may fail
30
30
  end
31
31
 
32
- def test_01_add_local_user
33
- assert_respond_to(Admin, :add_local_user)
34
- assert_nothing_raised{ Admin.add_local_user('foo') }
35
- end
36
-
37
- def test_add_global_user
38
- assert_respond_to(Admin, :add_global_user)
39
- end
40
-
41
- def test_02_config_local_user
42
- assert_respond_to(Admin, :config_local_user)
32
+ # Admin singleton methods
33
+
34
+ def test_01_add_user
35
+ assert_respond_to(Admin, :add_user)
43
36
  assert_nothing_raised{
44
- Admin.config_local_user("foo", {
45
- :description => "delete me",
46
- :fullname => "fubar"
47
- })
37
+ Admin.add_user(:name => 'foo', :password => 'a1b2c3D4')
48
38
  }
49
39
  end
50
-
51
- def test_config_global_user
52
- assert_respond_to(Admin, :config_global_user)
53
- end
54
-
55
- def test_03_delete_local_user
56
- assert_respond_to(Admin, :delete_local_user)
57
- assert_nothing_raised{ Admin.delete_local_user("foo") }
58
- end
59
-
60
- def test_delete_global_user
61
- assert_respond_to(Admin, :delete_global_user)
40
+
41
+ def test_02_config_user
42
+ assert_respond_to(Admin, :configure_user)
43
+ assert_nothing_raised{
44
+ Admin.configure_user(
45
+ :name => 'foo',
46
+ :description => 'delete me',
47
+ :fullname => 'fubar',
48
+ :password => ['a1b2c3D4', 'd1c2b3A4']
49
+ )
50
+ }
62
51
  end
63
52
 
64
- def test_01_add_local_group
65
- assert_respond_to(Admin, :add_local_group)
66
- assert_nothing_raised{ Admin.add_local_group("bar") }
53
+ def test_03_delete_user
54
+ assert_respond_to(Admin, :delete_user)
55
+ assert_nothing_raised{ Admin.delete_user('foo') }
67
56
  end
68
-
69
- def test_add_global_group
70
- assert_respond_to(Admin, :add_global_group)
57
+
58
+ def test_01_add_group
59
+ assert_respond_to(Admin, :add_group)
60
+ assert_nothing_raised{ Admin.add_group(:name => 'bar') }
71
61
  end
72
62
 
73
- def test_02_config_local_group
74
- assert_respond_to(Admin, :config_local_group)
63
+ def test_02_configure_group
64
+ assert_respond_to(Admin, :configure_group)
75
65
  assert_nothing_raised{
76
- Admin.config_local_group('bar', {:description => 'delete me'})
66
+ Admin.configure_group(:name => 'bar', :description => 'delete me')
77
67
  }
78
68
  end
79
69
 
80
- def test_config_global_group
81
- assert_respond_to(Admin, :config_global_group)
82
- end
83
-
84
- def test_03_delete_local_group
85
- assert_respond_to(Admin, :delete_local_group)
86
- assert_nothing_raised{ Admin.delete_local_group("bar") }
70
+ def test_03_delete_group
71
+ assert_respond_to(Admin, :delete_group)
72
+ assert_nothing_raised{ Admin.delete_group('bar') }
87
73
  end
88
74
 
89
- def test_delete_global_group
90
- assert_respond_to(Admin, :delete_global_group)
75
+ def test_get_login_basic
76
+ assert_respond_to(Admin, :get_login)
77
+ assert_nothing_raised{ Admin.get_login }
91
78
  end
92
79
 
93
80
  def test_get_login
94
- assert_respond_to(Admin, :get_login)
95
- assert_nothing_raised{ Admin.get_login }
96
81
  assert_kind_of(String, Admin.get_login)
97
82
  end
83
+
84
+ def test_get_login_expected_errors
85
+ assert_raise(ArgumentError){ Admin.get_login('foo') }
86
+ end
98
87
 
99
- def test_get_user
88
+ def test_get_user_basic
100
89
  assert_respond_to(Admin, :get_user)
101
- assert_raises(ArgumentError){ Admin.get_user }
102
90
  end
103
91
 
104
- def test_get_user_local
105
- assert_nothing_raised{ Admin.get_user(@user_name) }
106
- assert_nothing_raised{ Admin.get_user(@user_id) }
107
- assert_kind_of(User, Admin.get_user(@user_name))
108
- assert_kind_of(User, Admin.get_user(@user_id))
92
+ def test_get_user_by_string
93
+ assert_nothing_raised{ Admin.get_user(@user_name, :localaccount => true) }
94
+ assert_kind_of(User, Admin.get_user(@user_name, :localaccount => true))
95
+ end
96
+
97
+ def test_get_user_by_uid
98
+ assert_nothing_raised{ Admin.get_user(@user_id, :localaccount => true) }
99
+ assert_kind_of(User, Admin.get_user(@user_id, :localaccount => true))
109
100
  end
110
101
 
111
- def test_get_user_remote
112
- assert_nothing_raised{ Admin.get_user(@user_name, @@host) }
113
- assert_nothing_raised{ Admin.get_user(@user_id, @@host) }
114
- assert_kind_of(User, Admin.get_user(@user_name, @@host))
115
- assert_kind_of(User, Admin.get_user(@user_id, @@host))
102
+ def test_get_user_by_string_with_options
103
+ options = {:host => @@host, :localaccount => true}
104
+ assert_nothing_raised{ Admin.get_user(@user_name, options) }
105
+ assert_kind_of(User, Admin.get_user(@user_name, options))
106
+ end
107
+
108
+ def test_get_user_by_uid_with_options
109
+ options = {:host => @@host, :localaccount => true}
110
+ assert_nothing_raised{ Admin.get_user(@user_id, options) }
111
+ assert_kind_of(User, Admin.get_user(@user_id, options))
112
+ end
113
+
114
+ def test_get_user_expected_errors
115
+ assert_raises(ArgumentError){ Admin.get_user }
116
116
  end
117
117
 
118
- def test_users
118
+ def test_users_basic
119
119
  assert_respond_to(Admin, :users)
120
+ assert_nothing_raised{ Admin.users(:localaccount => true) }
120
121
  end
121
122
 
122
- def test_users_local
123
- assert_nothing_raised{ Admin.users }
124
- assert_nothing_raised{ Admin.users{ |u| } }
125
- assert_nothing_raised{ Admin.users(nil) }
126
- assert_nothing_raised{ Admin.users(nil){ |u| } }
127
- assert_kind_of(Array, Admin.users)
128
- assert_kind_of(User, Admin.users.first)
123
+ def test_users
124
+ assert_kind_of(Array, Admin.users(:localaccount => true))
125
+ assert_kind_of(User, Admin.users(:localaccount => true).first)
126
+ end
127
+
128
+ def test_users_with_block
129
+ array = []
130
+ assert_nothing_raised{
131
+ Admin.users(:localaccount => true){ |u| array << u }
132
+ }
133
+ assert_kind_of(User, array[0])
134
+ end
135
+
136
+ def test_get_group_basic
137
+ assert_respond_to(Admin, :get_group)
138
+ end
139
+
140
+ def test_get_group_by_name
141
+ assert_nothing_raised{ Admin.get_group(@group_name, :localaccount => true) }
142
+ assert_kind_of(Group, Admin.get_group(@group_name, :localaccount => true))
143
+ end
144
+
145
+ def test_get_group_by_gid
146
+ assert_nothing_raised{ Admin.get_group(@group_id, :localaccount => true) }
147
+ assert_kind_of(Group, Admin.get_group(@group_id, :localaccount => true))
129
148
  end
130
149
 
131
- def test_users_remote
132
- assert_nothing_raised{ Admin.users(@@host) }
133
- assert_nothing_raised{ Admin.users(@@host){ |u| } }
150
+ def test_get_group_with_options
151
+ assert_nothing_raised{ Admin.get_group(@group_name, :localaccount => true) }
152
+ assert_kind_of(Group, Admin.get_group(@group_name, :localaccount => true))
153
+ end
154
+
155
+ def test_get_group_expected_errors
156
+ assert_raise(ArgumentError){ Admin.get_group }
134
157
  end
135
158
 
159
+ def test_groups_basic
160
+ assert_respond_to(Admin, :groups)
161
+ assert_nothing_raised{ Admin.groups(:localaccount => true) }
162
+ end
163
+
164
+ def test_groups
165
+ assert_kind_of(Array, Admin.groups(:localaccount => true))
166
+ assert_kind_of(Group, Admin.groups(:localaccount => true).first)
167
+ end
168
+
169
+ def test_groups_with_block
170
+ array = []
171
+ assert_nothing_raised{
172
+ Admin.groups(:localaccount => true){ |g| array << g }
173
+ }
174
+ assert_kind_of(Group, array[0])
175
+ end
176
+
177
+ # User class
178
+
136
179
  def test_user_instance_caption
137
180
  assert_respond_to(@user, :caption)
138
181
  assert_respond_to(@user, :caption=)
@@ -213,40 +256,7 @@ class TC_Sys_Admin_Win32 < Test::Unit::TestCase
213
256
  assert_respond_to(@user, :uid=)
214
257
  end
215
258
 
216
- def test_get_group
217
- assert_respond_to(Admin, :get_group)
218
- assert_raises(ArgumentError){ Admin.get_group }
219
- end
220
-
221
- def test_get_group_local
222
- assert_nothing_raised{ Admin.get_group(@group_name) }
223
- assert_kind_of(Group, Admin.get_group(@group_name))
224
- assert_nothing_raised{ Admin.get_group(@group_id) }
225
- assert_kind_of(Group, Admin.get_group(@group_id))
226
- end
227
-
228
- def test_get_group_remote
229
- assert_nothing_raised{ Admin.get_group(@group_name, @@host) }
230
- assert_kind_of(Group, Admin.get_group(@group_name, @@host))
231
- end
232
-
233
- def test_groups
234
- assert_respond_to(Admin, :groups)
235
- end
236
-
237
- def test_groups_local
238
- assert_nothing_raised{ Admin.groups }
239
- assert_nothing_raised{ Admin.groups{ |g| } }
240
- assert_kind_of(Array, Admin.groups)
241
- assert_kind_of(Group, Admin.groups.first)
242
- end
243
-
244
- def test_groups_remote
245
- assert_nothing_raised{ Admin.groups(@@host) }
246
- assert_nothing_raised{ Admin.groups(@@host){ |g| } }
247
- assert_kind_of(Array, Admin.groups(@@host))
248
- assert_kind_of(Group, Admin.groups(@@host).first)
249
- end
259
+ # Group class
250
260
 
251
261
  def test_group_instance_caption
252
262
  assert_respond_to(@group, :caption)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sys-admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.5
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel J. Berger
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-26 00:00:00 -07:00
12
+ date: 2009-03-29 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -27,19 +27,21 @@ extra_rdoc_files:
27
27
  files:
28
28
  - doc/sys-admin-unix.txt
29
29
  - doc/sys-admin-windows.txt
30
- - examples/users.rb
31
30
  - examples/groups.rb
32
- - test/test_sys_admin_windows.rb
31
+ - examples/users.rb
33
32
  - test/test_sys_admin.rb
34
33
  - test/test_sys_admin_unix.rb
35
- - MANIFEST
36
- - README
34
+ - test/test_sys_admin_windows.rb
37
35
  - CHANGES
36
+ - MANIFEST
38
37
  - Rakefile
38
+ - README
39
39
  - ext/sys/admin.c
40
40
  - ext/sys/admin.h
41
41
  has_rdoc: true
42
42
  homepage: http://www.rubyforge.org/projects/sysutils
43
+ licenses: []
44
+
43
45
  post_install_message:
44
46
  rdoc_options: []
45
47
 
@@ -60,9 +62,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
60
62
  requirements: []
61
63
 
62
64
  rubyforge_project: sysutils
63
- rubygems_version: 1.3.1
65
+ rubygems_version: 1.3.1.2403
64
66
  signing_key:
65
- specification_version: 2
67
+ specification_version: 3
66
68
  summary: A unified, cross platform replacement for the "etc" library.
67
69
  test_files:
68
70
  - test/test_sys_admin.rb