1
/************************************************
6
$Date: 2007-02-13 08:01:19 +0900 (Tue, 13 Feb 2007) $
7
created at: Tue Mar 22 18:39:19 JST 1994
9
************************************************/
13
#include <sys/types.h>
26
#ifndef HAVE_TYPE_UID_T
30
static VALUE sPasswd, sGroup;
37
/* Returns the short user name of the currently logged in user.
40
* Etc.getlogin -> 'guest'
51
if (!login) login = getenv("USER");
53
login = getenv("USER");
57
return rb_tainted_str_new2(login);
61
#if defined(HAVE_GETPWENT) || defined(HAVE_GETGRENT)
66
if (str == 0) str = "";
67
return rb_tainted_str_new2(str);
76
if (pwd == 0) rb_sys_fail("/etc/passwd");
77
return rb_struct_new(sPasswd,
78
safe_setup_str(pwd->pw_name),
79
#ifdef HAVE_ST_PW_PASSWD
80
safe_setup_str(pwd->pw_passwd),
82
PW_UID2VAL(pwd->pw_uid),
83
PW_GID2VAL(pwd->pw_gid),
84
#ifdef HAVE_ST_PW_GECOS
85
safe_setup_str(pwd->pw_gecos),
87
safe_setup_str(pwd->pw_dir),
88
safe_setup_str(pwd->pw_shell),
89
#ifdef HAVE_ST_PW_CHANGE
90
INT2NUM(pwd->pw_change),
92
#ifdef HAVE_ST_PW_QUOTA
93
INT2NUM(pwd->pw_quota),
96
PW_AGE2VAL(pwd->pw_age),
98
#ifdef HAVE_ST_PW_CLASS
99
safe_setup_str(pwd->pw_class),
101
#ifdef HAVE_ST_PW_COMMENT
102
safe_setup_str(pwd->pw_comment),
104
#ifdef HAVE_ST_PW_EXPIRE
105
INT2NUM(pwd->pw_expire),
112
/* Returns the /etc/passwd information for the user with specified integer
115
* The information is returned as a Struct::Passwd; see getpwent above for
118
* e.g. * Etc.getpwuid(0) -> #<struct Struct::Passwd name="root",
119
* passwd="x", uid=0, gid=0, gecos="root",dir="/root", shell="/bin/bash">
122
etc_getpwuid(argc, argv, obj)
127
#if defined(HAVE_GETPWENT)
133
if (rb_scan_args(argc, argv, "01", &id) == 1) {
134
uid = PW_VAL2UID(id);
140
if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %d", uid);
141
return setup_passwd(pwd);
147
/* Returns the /etc/passwd information for the user with specified login name.
149
* The information is returned as a Struct::Passwd; see getpwent above for
152
* e.g. * Etc.getpwnam('root') -> #<struct Struct::Passwd name="root",
153
* passwd="x", uid=0, gid=0, gecos="root",dir="/root", shell="/bin/bash">
156
etc_getpwnam(obj, nam)
162
SafeStringValue(nam);
163
pwd = getpwnam(RSTRING(nam)->ptr);
164
if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %s", RSTRING(nam)->ptr);
165
return setup_passwd(pwd);
172
static int passwd_blocking = 0;
176
passwd_blocking = Qfalse;
186
while (pw = getpwent()) {
187
rb_yield(setup_passwd(pw));
194
/* Provides a convenient Ruby iterator which executes a block for each entry
195
* in the /etc/passwd file.
197
* The code block is passed an Etc::Passwd struct; see getpwent above for
205
* puts u.name + " = " + u.gecos
217
if (rb_block_given_p()) {
218
if (passwd_blocking) {
219
rb_raise(rb_eRuntimeError, "parallel passwd iteration");
221
passwd_blocking = Qtrue;
222
rb_ensure(passwd_iterate, 0, passwd_ensure, 0);
224
if (pw = getpwent()) {
225
return setup_passwd(pw);
231
/* Resets the process of reading the /etc/passwd file, so that the next call
232
* to getpwent will return the first entry again.
244
/* Ends the process of scanning through the /etc/passwd file begun with
245
* getpwent, and closes the file.
257
/* Returns an entry from the /etc/passwd file. The first time it is called it
258
* opens the file and returns the first entry; each successive call returns
259
* the next entry, or nil if the end of the file has been reached.
261
* To close the file when processing is complete, call endpwent.
263
* Each entry is returned as a Struct::Passwd:
265
* - Passwd#name contains the short login name of the user as a String.
267
* - Passwd#passwd contains the encrypted password of the user as a String.
268
* an 'x' is returned if shadow passwords are in use. An '*' is returned
269
* if the user cannot log in using a password.
271
* - Passwd#uid contains the integer user ID (uid) of the user.
273
* - Passwd#gid contains the integer group ID (gid) of the user's primary group.
275
* - Passwd#gecos contains a longer String description of the user, such as
276
* a full name. Some Unix systems provide structured information in the
277
* gecos field, but this is system-dependent.
279
* - Passwd#dir contains the path to the home directory of the user as a String.
281
* - Passwd#shell contains the path to the login shell of the user as a String.
290
if (pw = getpwent()) {
291
return setup_passwd(pw);
308
rb_ary_push(mem, safe_setup_str(*tbl));
311
return rb_struct_new(sGroup,
312
safe_setup_str(grp->gr_name),
313
#ifdef HAVE_ST_GR_PASSWD
314
safe_setup_str(grp->gr_passwd),
316
PW_GID2VAL(grp->gr_gid),
321
/* Returns information about the group with specified integer group id (gid),
322
* as found in /etc/group.
324
* The information is returned as a Struct::Group; see getgrent above for
327
* e.g. Etc.getgrgid(100) -> #<struct Struct::Group name="users", passwd="x",
328
* gid=100, mem=["meta", "root"]>
332
etc_getgrgid(obj, id)
342
if (grp == 0) rb_raise(rb_eArgError, "can't find group for %d", gid);
343
return setup_group(grp);
349
/* Returns information about the group with specified String name, as found
352
* The information is returned as a Struct::Group; see getgrent above for
355
* e.g. Etc.getgrnam('users') -> #<struct Struct::Group name="users",
356
* passwd="x", gid=100, mem=["meta", "root"]>
360
etc_getgrnam(obj, nam)
367
SafeStringValue(nam);
368
grp = getgrnam(RSTRING(nam)->ptr);
369
if (grp == 0) rb_raise(rb_eArgError, "can't find group for %s", RSTRING(nam)->ptr);
370
return setup_group(grp);
377
static int group_blocking = 0;
381
group_blocking = Qfalse;
391
while (pw = getgrent()) {
392
rb_yield(setup_group(pw));
399
/* Provides a convenient Ruby iterator which executes a block for each entry
400
* in the /etc/group file.
402
* The code block is passed an Etc::Group struct; see getgrent above for
410
* puts g.name + ": " + g.mem.join(', ')
422
if (rb_block_given_p()) {
423
if (group_blocking) {
424
rb_raise(rb_eRuntimeError, "parallel group iteration");
426
group_blocking = Qtrue;
427
rb_ensure(group_iterate, 0, group_ensure, 0);
429
if (grp = getgrent()) {
430
return setup_group(grp);
436
/* Resets the process of reading the /etc/group file, so that the next call
437
* to getgrent will return the first entry again.
449
/* Ends the process of scanning through the /etc/group file begun by
450
* getgrent, and closes the file.
462
/* Returns an entry from the /etc/group file. The first time it is called it
463
* opens the file and returns the first entry; each successive call returns
464
* the next entry, or nil if the end of the file has been reached.
466
* To close the file when processing is complete, call endgrent.
468
* Each entry is returned as a Struct::Group:
470
* - Group#name contains the name of the group as a String.
472
* - Group#passwd contains the encrypted password as a String. An 'x' is
473
* returned if password access to the group is not available; an empty
474
* string is returned if no password is needed to obtain membership of
477
* - Group#gid contains the group's numeric ID as an integer.
479
* - Group#mem is an Array of Strings containing the short login names of the
480
* members of the group.
489
if (gr = getgrent()) {
490
return setup_group(gr);
498
/* The etc module provides access to information from the /etc/passwd and
499
* /etc/group files on Linux and Unix systems.
501
* Documented by mathew <meta@pobox.com>.
506
mEtc = rb_define_module("Etc");
508
rb_define_module_function(mEtc, "getlogin", etc_getlogin, 0);
510
rb_define_module_function(mEtc, "getpwuid", etc_getpwuid, -1);
511
rb_define_module_function(mEtc, "getpwnam", etc_getpwnam, 1);
512
rb_define_module_function(mEtc, "setpwent", etc_setpwent, 0);
513
rb_define_module_function(mEtc, "endpwent", etc_endpwent, 0);
514
rb_define_module_function(mEtc, "getpwent", etc_getpwent, 0);
515
rb_define_module_function(mEtc, "passwd", etc_passwd, 0);
517
rb_define_module_function(mEtc, "getgrgid", etc_getgrgid, 1);
518
rb_define_module_function(mEtc, "getgrnam", etc_getgrnam, 1);
519
rb_define_module_function(mEtc, "group", etc_group, 0);
520
rb_define_module_function(mEtc, "setgrent", etc_setgrent, 0);
521
rb_define_module_function(mEtc, "endgrent", etc_endgrent, 0);
522
rb_define_module_function(mEtc, "getgrent", etc_getgrent, 0);
524
rb_global_variable(&sPasswd);
525
sPasswd = rb_struct_define("Passwd",
526
"name", "passwd", "uid", "gid",
527
#ifdef HAVE_ST_PW_GECOS
531
#ifdef HAVE_ST_PW_CHANGE
534
#ifdef HAVE_ST_PW_QUOTA
537
#ifdef HAVE_ST_PW_AGE
540
#ifdef HAVE_ST_PW_CLASS
543
#ifdef HAVE_ST_PW_COMMENT
546
#ifdef HAVE_ST_PW_EXPIRE
552
rb_global_variable(&sGroup);
553
sGroup = rb_struct_define("Group", "name",
554
#ifdef HAVE_ST_GR_PASSWD