sys-admin 1.3.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/CHANGES +31 -0
- data/MANIFEST +17 -0
- data/README +174 -0
- data/examples/groups.rb +39 -0
- data/examples/users.rb +35 -0
- data/extconf.rb +62 -0
- data/lib/sys/unix.c +283 -0
- data/lib/sys/unix.h +411 -0
- data/lib/sys/win32.orig +403 -0
- data/test/tc_admin.rb +14 -0
- data/test/tc_unix.rb +78 -0
- data/test/tc_win32.rb +248 -0
- metadata +57 -0
data/CHANGES
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
== 1.3.1 - 29-Jun-2005
|
2
|
+
* Fixed a bug where the inability to read the lastlog file caused an error.
|
3
|
+
From now on that error is ignored, and the lastlog attributes of the User
|
4
|
+
object are set to nil.
|
5
|
+
* Added a beta version of Admin.delete_user (Windows only).
|
6
|
+
|
7
|
+
== 1.3.0 - 3-Jun-2005
|
8
|
+
* Bug fixes for Linux.
|
9
|
+
* Removed the version.h file - no longer needed since the Win32 version is
|
10
|
+
pure Ruby.
|
11
|
+
|
12
|
+
== 1.2.0 - 30-Apr-2005
|
13
|
+
* Replaced the Win32 version with a pure Ruby version that uses Win32API and
|
14
|
+
win32ole + WMI.
|
15
|
+
* The LocalGroup class no longer exists in the Win32 version. Instead, it is
|
16
|
+
now an attribute of a Group object. The issue was forced by WMI.
|
17
|
+
* The default for users and groups on Win32 systems is now local rather than
|
18
|
+
global. See the documentation for why you probably don't want to iterate
|
19
|
+
over global accounts.
|
20
|
+
* Corresponding doc changes and test suite changes.
|
21
|
+
|
22
|
+
== 1.1.0 - 1-Apr-2005
|
23
|
+
* Fixed bug where a segfault could occur when trying to retrieve a user or
|
24
|
+
group by an ID that didn't exist (Unix).
|
25
|
+
* Added tests for intentional failures.
|
26
|
+
* Added lastlog information tothe User class (Unix).
|
27
|
+
* Modified the way User objects are created internally (Unix).
|
28
|
+
* Fixed a bug in the User#shell attribute (Unix).
|
29
|
+
|
30
|
+
== 1.0.0 - 25-Mar-2005
|
31
|
+
* Initial release
|
data/MANIFEST
ADDED
data/README
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
== Description
|
2
|
+
The sys-admin package is a unified, cross platform replacement for the
|
3
|
+
Etc module.
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
=== Win32
|
7
|
+
ruby test\tc_admin.rb # optional
|
8
|
+
ruby install.rb
|
9
|
+
|
10
|
+
=== Unix
|
11
|
+
ruby extconf.rb
|
12
|
+
nmake
|
13
|
+
ruby test\tc_admin.rb # optional
|
14
|
+
nmake site-install
|
15
|
+
|
16
|
+
== Synopsis
|
17
|
+
require "sys/admin"
|
18
|
+
include Sys
|
19
|
+
|
20
|
+
# Yields a User object for each user
|
21
|
+
Admin.users{ |user|
|
22
|
+
p user
|
23
|
+
}
|
24
|
+
|
25
|
+
# Returns an Array of User objects
|
26
|
+
a = Admin.users
|
27
|
+
|
28
|
+
# Yields a Group object for each group
|
29
|
+
Admin.groups{ |group|
|
30
|
+
p group
|
31
|
+
}
|
32
|
+
|
33
|
+
# Returns an Array of Group objects
|
34
|
+
g = Admin.groups
|
35
|
+
|
36
|
+
# Get information about a particular user
|
37
|
+
p Admin.get_user("nobody")
|
38
|
+
|
39
|
+
# Get information about a particular group
|
40
|
+
p Admin.get_group("adm")
|
41
|
+
|
42
|
+
== Admin
|
43
|
+
Admin.get_login
|
44
|
+
Returns the user name (only) of the current login.
|
45
|
+
|
46
|
+
Admin.get_user(name, host=localhost)
|
47
|
+
Admin.get_user(uid, host=localhost, local=true)
|
48
|
+
Returns a User object based on +name+ or +uid+.
|
49
|
+
|
50
|
+
Win32 only: you may specify a host from which information is retrieved.
|
51
|
+
The default is the local machine. You may also specify whether to
|
52
|
+
retrieve a local or global account. The default is local.
|
53
|
+
|
54
|
+
Admin.get_group(name, host=localhost, local=true)
|
55
|
+
Admin.get_group(gid, host=localhost, local=true)
|
56
|
+
Returns a Group object based on +name+ or +uid+.
|
57
|
+
|
58
|
+
Win32 only: you may specify a host from which information is retrieved.
|
59
|
+
The default is the local machine. You can retrieve either a global or
|
60
|
+
local group, depending on the value of the +local+ argument.
|
61
|
+
|
62
|
+
Admin.groups(host=localhost, local=true)
|
63
|
+
Admin.groups(host=localhost, local=true){ |group| ... }
|
64
|
+
In block form, yields a Group object for each user on the system. In
|
65
|
+
non-block form, returns an Array of Group objects.
|
66
|
+
|
67
|
+
Win32 only: you may specify a host from which information is retrieved.
|
68
|
+
The default is the local machine. You can retrieve either a global or
|
69
|
+
local group, depending on the value of the +local+ argument.
|
70
|
+
|
71
|
+
Admin.users(host=localhost, local=true)
|
72
|
+
Admin.users(host=localhost, local=true){ |user| ... }
|
73
|
+
In block form, yields a User object for each user on the system. In
|
74
|
+
non-block form, returns an Array of User objects.
|
75
|
+
|
76
|
+
Win32 only: you may specify a host from which information is retrieved.
|
77
|
+
The default is the local machine. You can retrieve either a global or
|
78
|
+
local group, depending on the value of the +local+ argument.
|
79
|
+
|
80
|
+
== User class
|
81
|
+
=== User (Win32)
|
82
|
+
The User class has the following attributes on Win32 systems:
|
83
|
+
|
84
|
+
* account_type
|
85
|
+
* caption
|
86
|
+
* description
|
87
|
+
* domain
|
88
|
+
* password
|
89
|
+
* full_name
|
90
|
+
* install_date
|
91
|
+
* name
|
92
|
+
* sid
|
93
|
+
* status
|
94
|
+
* disabled?
|
95
|
+
* local?
|
96
|
+
* lockout?
|
97
|
+
* password_changeable?
|
98
|
+
* password_expires?
|
99
|
+
* password_required?
|
100
|
+
|
101
|
+
=== User (Unix)
|
102
|
+
The User class has the following attributes on Unix systems:
|
103
|
+
|
104
|
+
* name
|
105
|
+
* passwd
|
106
|
+
* uid
|
107
|
+
* gid
|
108
|
+
* dir
|
109
|
+
* shell
|
110
|
+
* gecos
|
111
|
+
* quota
|
112
|
+
* age
|
113
|
+
* class
|
114
|
+
* comment
|
115
|
+
* expire
|
116
|
+
|
117
|
+
== Group Classes
|
118
|
+
=== Group (Win32)
|
119
|
+
The Group class has the following attributes on Win32 systems:
|
120
|
+
|
121
|
+
* caption
|
122
|
+
* description
|
123
|
+
* domain
|
124
|
+
* install_date
|
125
|
+
* name
|
126
|
+
* sid
|
127
|
+
* status
|
128
|
+
* gid
|
129
|
+
* local?
|
130
|
+
|
131
|
+
=== Group (Unix)
|
132
|
+
The Group class has the following attributes on Unix systems:
|
133
|
+
|
134
|
+
* name
|
135
|
+
* gid
|
136
|
+
* members
|
137
|
+
* passwd
|
138
|
+
|
139
|
+
== Error Classes
|
140
|
+
AdminError < StandardError
|
141
|
+
Raised if anything goes wrong with any of the above methods.
|
142
|
+
|
143
|
+
== Developer's Notes
|
144
|
+
=== Win32
|
145
|
+
The Win32 version now uses a win32ole + WMI approach to getting
|
146
|
+
information. This means that the WMI service must be running on the
|
147
|
+
target machine in order to work (which it is, by default).
|
148
|
+
|
149
|
+
Note that, by default, local user and group information is retrieved
|
150
|
+
instead of global. You probably do NOT want to iterate over global users
|
151
|
+
or groups because there can be quite a few on your domain.
|
152
|
+
|
153
|
+
== Future Plans
|
154
|
+
The following methods will be added for both platforms:
|
155
|
+
|
156
|
+
* Admin.add_user
|
157
|
+
* Admin.config_user
|
158
|
+
* Admin.delete_user
|
159
|
+
|
160
|
+
== Known Bugs
|
161
|
+
None that I'm aware of. If you find any, please log them on the project
|
162
|
+
page at http://www.rubyforge.org/projects/sysutils.
|
163
|
+
|
164
|
+
== License
|
165
|
+
Ruby's
|
166
|
+
|
167
|
+
== Copyright
|
168
|
+
(C) 2005, Daniel J. Berger
|
169
|
+
All Rights Reserved
|
170
|
+
|
171
|
+
== Author
|
172
|
+
Daniel J. Berger
|
173
|
+
djberg96@yahoo.com
|
174
|
+
IRC nickname: imperator/mok/rubyhacker1
|
data/examples/groups.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
###########################################################################
|
2
|
+
# groups.rb
|
3
|
+
#
|
4
|
+
# Sample script to demonstrate some of the various group methods. Alter
|
5
|
+
# as you see fit.
|
6
|
+
###########################################################################
|
7
|
+
base = File.basename(Dir.pwd)
|
8
|
+
|
9
|
+
if base == "examples" || base =~ /sys-admin.*/
|
10
|
+
require "ftools"
|
11
|
+
Dir.chdir("..") if base == "examples"
|
12
|
+
Dir.mkdir("sys") unless File.exists?("sys")
|
13
|
+
if File::ALT_SEPARATOR
|
14
|
+
File.copy("lib/sys/win32.rb", "sys/admin.rb")
|
15
|
+
else
|
16
|
+
File.copy("admin.so","sys") if File.exists?("admin.so")
|
17
|
+
end
|
18
|
+
$LOAD_PATH.unshift(Dir.pwd)
|
19
|
+
end
|
20
|
+
|
21
|
+
require "pp"
|
22
|
+
require "sys/admin"
|
23
|
+
include Sys
|
24
|
+
|
25
|
+
if File::ALT_SEPARATOR
|
26
|
+
pp Admin.get_group("guests")
|
27
|
+
pp Admin.get_group(513)
|
28
|
+
else
|
29
|
+
pp Admin.get_group("adm")
|
30
|
+
pp Admin.get_group(7)
|
31
|
+
end
|
32
|
+
|
33
|
+
Admin.groups{ |g|
|
34
|
+
pp g
|
35
|
+
puts
|
36
|
+
}
|
37
|
+
|
38
|
+
# This should raise an error
|
39
|
+
Admin.get_group("fofofofof")
|
data/examples/users.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
###########################################################################
|
2
|
+
# users.rb
|
3
|
+
#
|
4
|
+
# Sample script to demonstrate some of the various user methods. Alter
|
5
|
+
# as you see fit.
|
6
|
+
###########################################################################
|
7
|
+
base = File.basename(Dir.pwd)
|
8
|
+
|
9
|
+
if base == "examples" || base =~ /sys-admin.*/
|
10
|
+
require "ftools"
|
11
|
+
Dir.chdir("..") if base == "examples"
|
12
|
+
Dir.mkdir("sys") unless File.exists?("sys")
|
13
|
+
if File::ALT_SEPARATOR
|
14
|
+
File.copy("lib/sys/win32.rb", "sys/admin.rb")
|
15
|
+
else
|
16
|
+
File.copy("admin.so","sys") if File.exists?("admin.so")
|
17
|
+
end
|
18
|
+
$LOAD_PATH.unshift(Dir.pwd)
|
19
|
+
end
|
20
|
+
|
21
|
+
require "pp"
|
22
|
+
require "sys/admin"
|
23
|
+
include Sys
|
24
|
+
|
25
|
+
user = Admin.get_login
|
26
|
+
|
27
|
+
puts "User: #{user}"
|
28
|
+
|
29
|
+
Admin.users{ |u|
|
30
|
+
pp u
|
31
|
+
puts
|
32
|
+
}
|
33
|
+
|
34
|
+
pp Admin.get_user(user)
|
35
|
+
pp Admin.get_user(501)
|
data/extconf.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require "mkmf"
|
2
|
+
require "ftools"
|
3
|
+
|
4
|
+
if PLATFORM.match('mswin')
|
5
|
+
STDERR.puts "Use the install.rb file on Win32 systems."
|
6
|
+
STDERR.puts "Exiting. The sys-admin package was NOT installed."
|
7
|
+
exit
|
8
|
+
else
|
9
|
+
File.move("lib/sys/win32.rb", "lib/sys/win32.orig") rescue nil # Don't install
|
10
|
+
|
11
|
+
have_func("getlogin_r")
|
12
|
+
have_func("getlogin")
|
13
|
+
have_func("getenv")
|
14
|
+
|
15
|
+
have_func("cuserid")
|
16
|
+
|
17
|
+
have_func("getpwuid_r")
|
18
|
+
have_func("getpwuid")
|
19
|
+
have_func("getpwnam_r")
|
20
|
+
have_func("getpwnam")
|
21
|
+
have_func("getpwent_r")
|
22
|
+
have_func("getpwent")
|
23
|
+
|
24
|
+
have_func("getgrgid_r")
|
25
|
+
have_func("getgrgid")
|
26
|
+
have_func("getgrnam_r")
|
27
|
+
have_func("getgrnam")
|
28
|
+
have_func("getgrent_r")
|
29
|
+
have_func("getgrent")
|
30
|
+
|
31
|
+
have_struct_member("struct passwd", "pw_gecos", "pwd.h")
|
32
|
+
have_struct_member("struct passwd", "pw_change", "pwd.h")
|
33
|
+
have_struct_member("struct passwd", "pw_quota", "pwd.h")
|
34
|
+
have_struct_member("struct passwd", "pw_age", "pwd.h")
|
35
|
+
have_struct_member("struct passwd", "pw_class", "pwd.h")
|
36
|
+
have_struct_member("struct passwd", "pw_comment", "pwd.h")
|
37
|
+
have_struct_member("struct passwd", "pw_expire", "pwd.h")
|
38
|
+
have_struct_member("struct passwd", "pw_passwd", "pwd.h")
|
39
|
+
|
40
|
+
have_struct_member("struct group", "gr_passwd", "grp.h")
|
41
|
+
|
42
|
+
utmp = have_header("utmp.h")
|
43
|
+
lastlog = have_header("lastlog.h")
|
44
|
+
|
45
|
+
if utmp || lastlog
|
46
|
+
have_struct_member(
|
47
|
+
"struct lastlog",
|
48
|
+
"ll_time",
|
49
|
+
["utmp.h", "time.h", "lastlog.h"]
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
$CFLAGS += " -D_POSIX_PTHREAD_SEMANTICS"
|
54
|
+
if PLATFORM.match("linux")
|
55
|
+
$CFLAGS += " -D_GNU_SOURCE -D_REENTRANT"
|
56
|
+
end
|
57
|
+
|
58
|
+
File.copy("lib/sys/unix.c", "admin.c")
|
59
|
+
File.copy("lib/sys/unix.h", "admin.h")
|
60
|
+
end
|
61
|
+
|
62
|
+
create_makefile("sys/admin")
|
data/lib/sys/unix.c
ADDED
@@ -0,0 +1,283 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
#include "admin.h"
|
3
|
+
|
4
|
+
/*
|
5
|
+
* call-seq:
|
6
|
+
* User.new
|
7
|
+
* User.new{ |user| ... }
|
8
|
+
*
|
9
|
+
* Creates and returns a User object. If a block is provided, yields the
|
10
|
+
* object back to the block.
|
11
|
+
*/
|
12
|
+
static VALUE user_init(VALUE self){
|
13
|
+
if(rb_block_given_p())
|
14
|
+
rb_yield(self);
|
15
|
+
|
16
|
+
return self;
|
17
|
+
}
|
18
|
+
|
19
|
+
/*
|
20
|
+
* call-seq:
|
21
|
+
* Group.new
|
22
|
+
* Group.new{ |user| ... }
|
23
|
+
*
|
24
|
+
* Creates and returns a Group object. If a block is provided, yields the
|
25
|
+
* object back to the block.
|
26
|
+
*/
|
27
|
+
static VALUE group_init(VALUE self){
|
28
|
+
if(rb_block_given_p())
|
29
|
+
rb_yield(self);
|
30
|
+
|
31
|
+
return self;
|
32
|
+
}
|
33
|
+
|
34
|
+
/*
|
35
|
+
* call-seq:
|
36
|
+
* Sys::Admin.get_login
|
37
|
+
*
|
38
|
+
* Returns the login for the process. If this is called from a process that
|
39
|
+
* has no controlling terminal, then it resorts to returning the "USER"
|
40
|
+
* environment variable. If that still isn't defined, nil is returned.
|
41
|
+
*
|
42
|
+
*--
|
43
|
+
* Developer's Note:
|
44
|
+
*
|
45
|
+
* Uses the (POSIX) reentrant version of getlogin_r() if supported. Otherwise
|
46
|
+
* it resorts to the standard getlogin function. If that fails, it resorts to
|
47
|
+
* cuserid(). If that fails, it resorts to getenv("USER"). If that fails,
|
48
|
+
* then nil is returned.
|
49
|
+
*/
|
50
|
+
static VALUE admin_get_login(VALUE klass){
|
51
|
+
char login[_POSIX_LOGIN_NAME_MAX];
|
52
|
+
VALUE rbLogin = Qnil;
|
53
|
+
|
54
|
+
#ifdef HAVE_GETLOGIN_R
|
55
|
+
getlogin_r(login,sizeof(login));
|
56
|
+
#elif HAVE_GETLOGIN
|
57
|
+
strcpy(login,getlogin());
|
58
|
+
#endif
|
59
|
+
|
60
|
+
#ifdef HAVE_CUSERID
|
61
|
+
if(!login)
|
62
|
+
cuserid(login);
|
63
|
+
#endif
|
64
|
+
|
65
|
+
#ifdef HAVE_GETENV
|
66
|
+
if(!login)
|
67
|
+
strcpy(login,getenv("USER"));
|
68
|
+
#endif
|
69
|
+
|
70
|
+
if(login)
|
71
|
+
rbLogin = rb_str_new2(login);
|
72
|
+
|
73
|
+
return rbLogin;
|
74
|
+
}
|
75
|
+
|
76
|
+
/* call-seq:
|
77
|
+
* Admin.get_user(name)
|
78
|
+
* Admin.get_user(uid)
|
79
|
+
*
|
80
|
+
* Returns a User object for the given +name+ or +uid+. Raises an AdminError
|
81
|
+
* if a user cannot be found for that name or user ID.
|
82
|
+
*/
|
83
|
+
static VALUE admin_get_user(VALUE klass, VALUE rbVal){
|
84
|
+
VALUE rbUser;
|
85
|
+
|
86
|
+
if(FIXNUM_P(rbVal)){
|
87
|
+
rbUser = get_user_by_num(rbVal);
|
88
|
+
}
|
89
|
+
else{
|
90
|
+
rbUser = get_user_by_name(rbVal);
|
91
|
+
}
|
92
|
+
|
93
|
+
return rbUser;
|
94
|
+
}
|
95
|
+
|
96
|
+
/* call-seq:
|
97
|
+
* Admin.get_group(name)
|
98
|
+
* Admin.get_group(gid)
|
99
|
+
*
|
100
|
+
* Returns a Group object for the given +name+ or +gid+. Raises an AdminError
|
101
|
+
* if a group cannot be found for that name or GID.
|
102
|
+
*
|
103
|
+
*--
|
104
|
+
* Developer's Note:
|
105
|
+
*
|
106
|
+
* I generally oppose method overloading like this, but for this method, and
|
107
|
+
* for only two types, I can live with it for the added convenience it
|
108
|
+
* provides.
|
109
|
+
*/
|
110
|
+
static VALUE admin_get_group(VALUE klass, VALUE rbVal){
|
111
|
+
VALUE rbGroup;
|
112
|
+
|
113
|
+
if(FIXNUM_P(rbVal)){
|
114
|
+
rbGroup = get_group_by_num(rbVal);
|
115
|
+
}
|
116
|
+
else{
|
117
|
+
rbGroup = get_group_by_name(rbVal);
|
118
|
+
}
|
119
|
+
|
120
|
+
return rbGroup;
|
121
|
+
}
|
122
|
+
|
123
|
+
/* call-seq:
|
124
|
+
* Admin.groups
|
125
|
+
* Admin.groups{ |group| ... }
|
126
|
+
*
|
127
|
+
* In block form, yields a Group object for each group on the system. In
|
128
|
+
* non-block form, returns an Array of Group objects.
|
129
|
+
*/
|
130
|
+
static VALUE admin_groups(VALUE klass){
|
131
|
+
VALUE rbArray = Qnil;
|
132
|
+
|
133
|
+
if(!rb_block_given_p())
|
134
|
+
rbArray = rb_ary_new();
|
135
|
+
|
136
|
+
setgrent();
|
137
|
+
|
138
|
+
#ifdef HAVE_GETGRENT_R
|
139
|
+
struct group grp;
|
140
|
+
char buf[GROUP_BUF_SIZE];
|
141
|
+
#ifdef _GNU_SOURCE
|
142
|
+
struct group* grp_p;
|
143
|
+
while(!getgrent_r(&grp, buf, GROUP_BUF_SIZE, &grp_p)){
|
144
|
+
if(rb_block_given_p()){
|
145
|
+
rb_yield(get_group(grp_p));
|
146
|
+
}
|
147
|
+
else{
|
148
|
+
rb_ary_push(rbArray, get_group(grp_p));
|
149
|
+
}
|
150
|
+
}
|
151
|
+
#else
|
152
|
+
while(getgrent_r(&grp, buf, GROUP_BUF_SIZE) != NULL){
|
153
|
+
if(rb_block_given_p()){
|
154
|
+
rb_yield(get_group(&grp));
|
155
|
+
}
|
156
|
+
else{
|
157
|
+
rb_ary_push(rbArray, get_group(&grp));
|
158
|
+
}
|
159
|
+
}
|
160
|
+
#endif
|
161
|
+
#elif HAVE_GETGRENT
|
162
|
+
struct group* grp;
|
163
|
+
while((grp = getgrent()) != NULL){
|
164
|
+
if(rb_block_given_p()){
|
165
|
+
rb_yield(get_group(grp));
|
166
|
+
}
|
167
|
+
else{
|
168
|
+
rb_ary_push(rbArray, get_group(grp));
|
169
|
+
}
|
170
|
+
}
|
171
|
+
#else
|
172
|
+
rb_raise(rb_eNotImpError, "groups method not supported on this platform");
|
173
|
+
#endif
|
174
|
+
|
175
|
+
endgrent();
|
176
|
+
return rbArray;
|
177
|
+
}
|
178
|
+
|
179
|
+
/* call-seq:
|
180
|
+
* Admin.users
|
181
|
+
* Admin.users{ |user| ... }
|
182
|
+
*
|
183
|
+
* In block form, yields a User object for each user on the system. In
|
184
|
+
* non-block form, returns an Array of User objects.
|
185
|
+
*/
|
186
|
+
static VALUE admin_users(VALUE klass){
|
187
|
+
VALUE rbArray = Qnil;
|
188
|
+
|
189
|
+
if(!rb_block_given_p())
|
190
|
+
rbArray = rb_ary_new();
|
191
|
+
|
192
|
+
setpwent();
|
193
|
+
|
194
|
+
#ifdef HAVE_GETPWENT_R
|
195
|
+
struct passwd pwd;
|
196
|
+
char buf[USER_BUF_SIZE];
|
197
|
+
|
198
|
+
#ifdef _GNU_SOURCE
|
199
|
+
struct passwd* pwd_p;
|
200
|
+
while(!getpwent_r(&pwd, buf, USER_BUF_SIZE, &pwd_p)){
|
201
|
+
if(rb_block_given_p()){
|
202
|
+
rb_yield(get_user(pwd_p));
|
203
|
+
}
|
204
|
+
else{
|
205
|
+
rb_ary_push(rbArray, get_user(pwd_p));
|
206
|
+
}
|
207
|
+
}
|
208
|
+
#else
|
209
|
+
while(getpwent_r(&pwd, buf, USER_BUF_SIZE) != NULL){
|
210
|
+
if(rb_block_given_p()){
|
211
|
+
rb_yield(get_user(&pwd));
|
212
|
+
}
|
213
|
+
else{
|
214
|
+
rb_ary_push(rbArray, get_user(&pwd));
|
215
|
+
}
|
216
|
+
}
|
217
|
+
#endif
|
218
|
+
#elif HAVE_GETPWENT
|
219
|
+
struct passwd* pwd;
|
220
|
+
|
221
|
+
while((pwd = getpwent()) != NULL){
|
222
|
+
if(rb_block_given_p()){
|
223
|
+
rb_yield(get_user(pwd));
|
224
|
+
}
|
225
|
+
else{
|
226
|
+
rb_ary_push(rbArray, get_user(pwd));
|
227
|
+
}
|
228
|
+
}
|
229
|
+
#else
|
230
|
+
rb_raise(rb_eNotImpError, "users method not supported on this platform");
|
231
|
+
#endif
|
232
|
+
|
233
|
+
endpwent();
|
234
|
+
return rbArray;
|
235
|
+
}
|
236
|
+
|
237
|
+
void Init_admin(){
|
238
|
+
VALUE mSys, cAdmin;
|
239
|
+
|
240
|
+
/* Module and class definitions */
|
241
|
+
mSys = rb_define_module("Sys");
|
242
|
+
cAdmin = rb_define_class_under(mSys, "Admin", rb_cObject);
|
243
|
+
cUser = rb_define_class_under(mSys, "User", rb_cObject);
|
244
|
+
cGroup = rb_define_class_under(mSys, "Group", rb_cObject);
|
245
|
+
cAdminError = rb_define_class_under(mSys, "AdminError", rb_eStandardError);
|
246
|
+
|
247
|
+
/* Class Methods */
|
248
|
+
rb_define_singleton_method(cAdmin, "get_login", admin_get_login, 0);
|
249
|
+
rb_define_singleton_method(cAdmin, "get_user", admin_get_user, 1);
|
250
|
+
rb_define_singleton_method(cAdmin, "get_group", admin_get_group, 1);
|
251
|
+
rb_define_singleton_method(cAdmin, "users", admin_users, 0);
|
252
|
+
rb_define_singleton_method(cAdmin, "groups", admin_groups, 0);
|
253
|
+
|
254
|
+
/* Instance Methods */
|
255
|
+
rb_define_method(cUser, "initialize", user_init, 0);
|
256
|
+
rb_define_method(cGroup,"initialize", group_init, 0);
|
257
|
+
|
258
|
+
/* User Attributes */
|
259
|
+
rb_define_attr(cUser, "name", 1, 1);
|
260
|
+
rb_define_attr(cUser, "passwd", 1, 1);
|
261
|
+
rb_define_attr(cUser, "uid", 1, 1);
|
262
|
+
rb_define_attr(cUser, "gid", 1, 1);
|
263
|
+
rb_define_attr(cUser, "dir", 1, 1);
|
264
|
+
rb_define_attr(cUser, "shell", 1, 1);
|
265
|
+
rb_define_attr(cUser, "gecos", 1, 1);
|
266
|
+
rb_define_attr(cUser, "quota", 1, 1);
|
267
|
+
rb_define_attr(cUser, "age", 1, 1);
|
268
|
+
rb_define_attr(cUser, "class", 1, 1);
|
269
|
+
rb_define_attr(cUser, "comment", 1, 1);
|
270
|
+
rb_define_attr(cUser, "expire", 1, 1);
|
271
|
+
rb_define_attr(cUser, "login_time", 1, 0);
|
272
|
+
rb_define_attr(cUser, "login_device", 1, 0);
|
273
|
+
rb_define_attr(cUser, "login_host", 1, 0);
|
274
|
+
|
275
|
+
/* Group Attributes */
|
276
|
+
rb_define_attr(cGroup, "name", 1, 1);
|
277
|
+
rb_define_attr(cGroup, "gid", 1, 1);
|
278
|
+
rb_define_attr(cGroup, "members", 1, 1);
|
279
|
+
rb_define_attr(cGroup, "passwd", 1, 1);
|
280
|
+
|
281
|
+
/* Constants */
|
282
|
+
rb_define_const(cAdmin, "VERSION", rb_str_new2(SYS_ADMIN_VERSION));
|
283
|
+
}
|