diff options
author | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-08-22 01:53:51 +0000 |
---|---|---|
committer | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-08-22 01:53:51 +0000 |
commit | 1e760c0be3ed35874204114e7454509f740c0fe2 (patch) | |
tree | a75eb2b1eea073830902d1fa49c568c4525c8b57 /ruby_1_8_6/ext/etc | |
parent | a2055d63b41a6678dc7aeb17d0bece314e700c5a (diff) |
add tag v1_8_6_71v1_8_5_71
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_8_5_71@13189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ruby_1_8_6/ext/etc')
-rw-r--r-- | ruby_1_8_6/ext/etc/.cvsignore | 3 | ||||
-rw-r--r-- | ruby_1_8_6/ext/etc/depend | 1 | ||||
-rw-r--r-- | ruby_1_8_6/ext/etc/etc.c | 559 | ||||
-rw-r--r-- | ruby_1_8_6/ext/etc/etc.txt | 72 | ||||
-rw-r--r-- | ruby_1_8_6/ext/etc/etc.txt.ja | 72 | ||||
-rw-r--r-- | ruby_1_8_6/ext/etc/extconf.rb | 43 |
6 files changed, 750 insertions, 0 deletions
diff --git a/ruby_1_8_6/ext/etc/.cvsignore b/ruby_1_8_6/ext/etc/.cvsignore new file mode 100644 index 0000000000..4088712231 --- /dev/null +++ b/ruby_1_8_6/ext/etc/.cvsignore @@ -0,0 +1,3 @@ +Makefile +mkmf.log +*.def diff --git a/ruby_1_8_6/ext/etc/depend b/ruby_1_8_6/ext/etc/depend new file mode 100644 index 0000000000..ac706477b0 --- /dev/null +++ b/ruby_1_8_6/ext/etc/depend @@ -0,0 +1 @@ +etc.o : etc.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h diff --git a/ruby_1_8_6/ext/etc/etc.c b/ruby_1_8_6/ext/etc/etc.c new file mode 100644 index 0000000000..486963378b --- /dev/null +++ b/ruby_1_8_6/ext/etc/etc.c @@ -0,0 +1,559 @@ +/************************************************ + + etc.c - + + $Author$ + $Date$ + created at: Tue Mar 22 18:39:19 JST 1994 + +************************************************/ + +#include "ruby.h" + +#include <sys/types.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#ifdef HAVE_GETPWENT +#include <pwd.h> +#endif + +#ifdef HAVE_GETGRENT +#include <grp.h> +#endif + +#ifndef HAVE_TYPE_UID_T +#define uid_t int +#endif + +static VALUE sPasswd, sGroup; + +#ifndef _WIN32 +char *getenv(); +#endif +char *getlogin(); + +/* Returns the short user name of the currently logged in user. + * + * e.g. + * Etc.getlogin -> 'guest' + */ +static VALUE +etc_getlogin(obj) + VALUE obj; +{ + char *login; + + rb_secure(4); +#ifdef HAVE_GETLOGIN + login = getlogin(); + if (!login) login = getenv("USER"); +#else + login = getenv("USER"); +#endif + + if (login) + return rb_tainted_str_new2(login); + return Qnil; +} + +#if defined(HAVE_GETPWENT) || defined(HAVE_GETGRENT) +static VALUE +safe_setup_str(str) + const char *str; +{ + if (str == 0) str = ""; + return rb_tainted_str_new2(str); +} +#endif + +#ifdef HAVE_GETPWENT +static VALUE +setup_passwd(pwd) + struct passwd *pwd; +{ + if (pwd == 0) rb_sys_fail("/etc/passwd"); + return rb_struct_new(sPasswd, + safe_setup_str(pwd->pw_name), +#ifdef HAVE_ST_PW_PASSWD + safe_setup_str(pwd->pw_passwd), +#endif + PW_UID2VAL(pwd->pw_uid), + PW_GID2VAL(pwd->pw_gid), +#ifdef HAVE_ST_PW_GECOS + safe_setup_str(pwd->pw_gecos), +#endif + safe_setup_str(pwd->pw_dir), + safe_setup_str(pwd->pw_shell), +#ifdef HAVE_ST_PW_CHANGE + INT2NUM(pwd->pw_change), +#endif +#ifdef HAVE_ST_PW_QUOTA + INT2NUM(pwd->pw_quota), +#endif +#ifdef HAVE_ST_PW_AGE + PW_AGE2VAL(pwd->pw_age), +#endif +#ifdef HAVE_ST_PW_CLASS + safe_setup_str(pwd->pw_class), +#endif +#ifdef HAVE_ST_PW_COMMENT + safe_setup_str(pwd->pw_comment), +#endif +#ifdef HAVE_ST_PW_EXPIRE + INT2NUM(pwd->pw_expire), +#endif + 0 /*dummy*/ + ); +} +#endif + +/* Returns the /etc/passwd information for the user with specified integer + * user id (uid). + * + * The information is returned as a Struct::Passwd; see getpwent above for + * details. + * + * e.g. * Etc.getpwuid(0) -> #<struct Struct::Passwd name="root", + * passwd="x", uid=0, gid=0, gecos="root",dir="/root", shell="/bin/bash"> + */ +static VALUE +etc_getpwuid(argc, argv, obj) + int argc; + VALUE *argv; + VALUE obj; +{ +#if defined(HAVE_GETPWENT) + VALUE id; + uid_t uid; + struct passwd *pwd; + + rb_secure(4); + if (rb_scan_args(argc, argv, "01", &id) == 1) { + uid = PW_VAL2UID(id); + } + else { + uid = getuid(); + } + pwd = getpwuid(uid); + if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %d", uid); + return setup_passwd(pwd); +#else + return Qnil; +#endif +} + +/* Returns the /etc/passwd information for the user with specified login name. + * + * The information is returned as a Struct::Passwd; see getpwent above for + * details. + * + * e.g. * Etc.getpwnam('root') -> #<struct Struct::Passwd name="root", + * passwd="x", uid=0, gid=0, gecos="root",dir="/root", shell="/bin/bash"> + */ +static VALUE +etc_getpwnam(obj, nam) + VALUE obj, nam; +{ +#ifdef HAVE_GETPWENT + struct passwd *pwd; + + SafeStringValue(nam); + pwd = getpwnam(RSTRING(nam)->ptr); + if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %s", RSTRING(nam)->ptr); + return setup_passwd(pwd); +#else + return Qnil; +#endif +} + +#ifdef HAVE_GETPWENT +static int passwd_blocking = 0; +static VALUE +passwd_ensure() +{ + passwd_blocking = Qfalse; + return Qnil; +} + +static VALUE +passwd_iterate() +{ + struct passwd *pw; + + setpwent(); + while (pw = getpwent()) { + rb_yield(setup_passwd(pw)); + } + endpwent(); + return Qnil; +} +#endif + +/* Provides a convenient Ruby iterator which executes a block for each entry + * in the /etc/passwd file. + * + * The code block is passed an Etc::Passwd struct; see getpwent above for + * details. + * + * Example: + * + * require 'etc' + * + * Etc.passwd {|u| + * puts u.name + " = " + u.gecos + * } + * + */ +static VALUE +etc_passwd(obj) + VALUE obj; +{ +#ifdef HAVE_GETPWENT + struct passwd *pw; + + rb_secure(4); + if (rb_block_given_p()) { + if (passwd_blocking) { + rb_raise(rb_eRuntimeError, "parallel passwd iteration"); + } + passwd_blocking = Qtrue; + rb_ensure(passwd_iterate, 0, passwd_ensure, 0); + } + if (pw = getpwent()) { + return setup_passwd(pw); + } +#endif + return Qnil; +} + +/* Resets the process of reading the /etc/passwd file, so that the next call + * to getpwent will return the first entry again. + */ +static VALUE +etc_setpwent(obj) + VALUE obj; +{ +#ifdef HAVE_GETPWENT + setpwent(); +#endif + return Qnil; +} + +/* Ends the process of scanning through the /etc/passwd file begun with + * getpwent, and closes the file. + */ +static VALUE +etc_endpwent(obj) + VALUE obj; +{ +#ifdef HAVE_GETPWENT + endpwent(); +#endif + return Qnil; +} + +/* Returns an entry from the /etc/passwd file. The first time it is called it + * opens the file and returns the first entry; each successive call returns + * the next entry, or nil if the end of the file has been reached. + * + * To close the file when processing is complete, call endpwent. + * + * Each entry is returned as a Struct::Passwd: + * + * - Passwd#name contains the short login name of the user as a String. + * + * - Passwd#passwd contains the encrypted password of the user as a String. + * an 'x' is returned if shadow passwords are in use. An '*' is returned + * if the user cannot log in using a password. + * + * - Passwd#uid contains the integer user ID (uid) of the user. + * + * - Passwd#gid contains the integer group ID (gid) of the user's primary group. + * + * - Passwd#gecos contains a longer String description of the user, such as + * a full name. Some Unix systems provide structured information in the + * gecos field, but this is system-dependent. + * + * - Passwd#dir contains the path to the home directory of the user as a String. + * + * - Passwd#shell contains the path to the login shell of the user as a String. + */ +static VALUE +etc_getpwent(obj) + VALUE obj; +{ +#ifdef HAVE_GETPWENT + struct passwd *pw; + + if (pw = getpwent()) { + return setup_passwd(pw); + } +#endif + return Qnil; +} + +#ifdef HAVE_GETGRENT +static VALUE +setup_group(grp) + struct group *grp; +{ + VALUE mem; + char **tbl; + + mem = rb_ary_new(); + tbl = grp->gr_mem; + while (*tbl) { + rb_ary_push(mem, safe_setup_str(*tbl)); + tbl++; + } + return rb_struct_new(sGroup, + safe_setup_str(grp->gr_name), +#ifdef HAVE_ST_GR_PASSWD + safe_setup_str(grp->gr_passwd), +#endif + PW_GID2VAL(grp->gr_gid), + mem); +} +#endif + +/* Returns information about the group with specified integer group id (gid), + * as found in /etc/group. + * + * The information is returned as a Struct::Group; see getgrent above for + * details. + * + * e.g. Etc.getgrgid(100) -> #<struct Struct::Group name="users", passwd="x", + * gid=100, mem=["meta", "root"]> + * + */ +static VALUE +etc_getgrgid(obj, id) + VALUE obj, id; +{ +#ifdef HAVE_GETGRENT + gid_t gid; + struct group *grp; + + rb_secure(4); + gid = PW_VAL2GID(id); + grp = getgrgid(gid); + if (grp == 0) rb_raise(rb_eArgError, "can't find group for %d", gid); + return setup_group(grp); +#else + return Qnil; +#endif +} + +/* Returns information about the group with specified String name, as found + * in /etc/group. + * + * The information is returned as a Struct::Group; see getgrent above for + * details. + * + * e.g. Etc.getgrnam('users') -> #<struct Struct::Group name="users", + * passwd="x", gid=100, mem=["meta", "root"]> + * + */ +static VALUE +etc_getgrnam(obj, nam) + VALUE obj, nam; +{ +#ifdef HAVE_GETGRENT + struct group *grp; + + rb_secure(4); + SafeStringValue(nam); + grp = getgrnam(RSTRING(nam)->ptr); + if (grp == 0) rb_raise(rb_eArgError, "can't find group for %s", RSTRING(nam)->ptr); + return setup_group(grp); +#else + return Qnil; +#endif +} + +#ifdef HAVE_GETGRENT +static int group_blocking = 0; +static VALUE +group_ensure() +{ + group_blocking = Qfalse; + return Qnil; +} + +static VALUE +group_iterate() +{ + struct group *pw; + + setgrent(); + while (pw = getgrent()) { + rb_yield(setup_group(pw)); + } + endgrent(); + return Qnil; +} +#endif + +/* Provides a convenient Ruby iterator which executes a block for each entry + * in the /etc/group file. + * + * The code block is passed an Etc::Group struct; see getgrent above for + * details. + * + * Example: + * + * require 'etc' + * + * Etc.group {|g| + * puts g.name + ": " + g.mem.join(', ') + * } + * + */ +static VALUE +etc_group(obj) + VALUE obj; +{ +#ifdef HAVE_GETGRENT + struct group *grp; + + rb_secure(4); + if (rb_block_given_p()) { + if (group_blocking) { + rb_raise(rb_eRuntimeError, "parallel group iteration"); + } + group_blocking = Qtrue; + rb_ensure(group_iterate, 0, group_ensure, 0); + } + if (grp = getgrent()) { + return setup_group(grp); + } +#endif + return Qnil; +} + +/* Resets the process of reading the /etc/group file, so that the next call + * to getgrent will return the first entry again. + */ +static VALUE +etc_setgrent(obj) + VALUE obj; +{ +#ifdef HAVE_GETGRENT + setgrent(); +#endif + return Qnil; +} + +/* Ends the process of scanning through the /etc/group file begun by + * getgrent, and closes the file. + */ +static VALUE +etc_endgrent(obj) + VALUE obj; +{ +#ifdef HAVE_GETGRENT + endgrent(); +#endif + return Qnil; +} + +/* Returns an entry from the /etc/group file. The first time it is called it + * opens the file and returns the first entry; each successive call returns + * the next entry, or nil if the end of the file has been reached. + * + * To close the file when processing is complete, call endgrent. + * + * Each entry is returned as a Struct::Group: + * + * - Group#name contains the name of the group as a String. + * + * - Group#passwd contains the encrypted password as a String. An 'x' is + * returned if password access to the group is not available; an empty + * string is returned if no password is needed to obtain membership of + * the group. + * + * - Group#gid contains the group's numeric ID as an integer. + * + * - Group#mem is an Array of Strings containing the short login names of the + * members of the group. + */ +static VALUE +etc_getgrent(obj) + VALUE obj; +{ +#ifdef HAVE_GETGRENT + struct group *gr; + + if (gr = getgrent()) { + return setup_group(gr); + } +#endif + return Qnil; +} + +static VALUE mEtc; + +/* The etc module provides access to information from the /etc/passwd and + * /etc/group files on Linux and Unix systems. + * + * Documented by mathew <meta@pobox.com>. + */ +void +Init_etc() +{ + mEtc = rb_define_module("Etc"); + + rb_define_module_function(mEtc, "getlogin", etc_getlogin, 0); + + rb_define_module_function(mEtc, "getpwuid", etc_getpwuid, -1); + rb_define_module_function(mEtc, "getpwnam", etc_getpwnam, 1); + rb_define_module_function(mEtc, "setpwent", etc_setpwent, 0); + rb_define_module_function(mEtc, "endpwent", etc_endpwent, 0); + rb_define_module_function(mEtc, "getpwent", etc_getpwent, 0); + rb_define_module_function(mEtc, "passwd", etc_passwd, 0); + + rb_define_module_function(mEtc, "getgrgid", etc_getgrgid, 1); + rb_define_module_function(mEtc, "getgrnam", etc_getgrnam, 1); + rb_define_module_function(mEtc, "group", etc_group, 0); + rb_define_module_function(mEtc, "setgrent", etc_setgrent, 0); + rb_define_module_function(mEtc, "endgrent", etc_endgrent, 0); + rb_define_module_function(mEtc, "getgrent", etc_getgrent, 0); + + rb_global_variable(&sPasswd); + sPasswd = rb_struct_define("Passwd", + "name", "passwd", "uid", "gid", +#ifdef HAVE_ST_PW_GECOS + "gecos", +#endif + "dir", "shell", +#ifdef HAVE_ST_PW_CHANGE + "change", +#endif +#ifdef HAVE_ST_PW_QUOTA + "quota", +#endif +#ifdef HAVE_ST_PW_AGE + "age", +#endif +#ifdef HAVE_ST_PW_CLASS + "uclass", +#endif +#ifdef HAVE_ST_PW_COMMENT + "comment", +#endif +#ifdef HAVE_ST_PW_EXPIRE + "expire", +#endif + NULL); + +#ifdef HAVE_GETGRENT + rb_global_variable(&sGroup); + sGroup = rb_struct_define("Group", "name", +#ifdef HAVE_ST_GR_PASSWD + "passwd", +#endif + "gid", "mem", NULL); +#endif +} diff --git a/ruby_1_8_6/ext/etc/etc.txt b/ruby_1_8_6/ext/etc/etc.txt new file mode 100644 index 0000000000..534790172c --- /dev/null +++ b/ruby_1_8_6/ext/etc/etc.txt @@ -0,0 +1,72 @@ +.\" etc.txt - -*- Indented-Text -*- created at: Fri Jul 14 00:47:15 JST 1995 + +** Etc(Module) + +The module to retrieve information under /etc directory. Available +only on UNIX platforms. All operations defined in this module are +module functions, so that you can include Etc module into your class. + +Module Function: + + getlogin + + returns login name of the user. It this fails, try getpwuid(). + + getpwnam(name) + + searches in /etc/passwd file (or equivalent database), and + returns password entry for the user. The return value is an + passwd structure, which has members described below. + + struct passwd + name # user name(string) + passwd # encrypted password(string) + uid # user ID(integer) + gid # group ID(integer) + gecos # gecos field(string) + dir # home directory(string) + shell # login shell(string) + # members below are optional + change # password change time(integer) + quota # quota value(integer) + age # password age(integer) + class # user access class(string) + comment # comment(string) + expire # account expiration time(integer) + end + + See getpwnam(3) for detail. + + getpwuid([uid]) + + returns passwd entry for the specified user id. If uid is + ommitted, use the value from getuid(). See getpwuid(3) for + detail. + + getgrgid(gid) + + searches in /etc/group file (or equivalent database), and + returns group entry for the group id. The return value is an + group structure, which has members described below. + + struct group + name # group name(string) + passwd # group password(string) + gid # group ID(integer) + mem # array of the group member names + end + + See getgrgid(3) for detail. + + getgrnam(name) + + returns the group entry for the specified name. The return + value is the group structure. See getgrnam(3) for detail. + + group + + iterates over all group entries. + + passwd + + iterates over all passwd entries. diff --git a/ruby_1_8_6/ext/etc/etc.txt.ja b/ruby_1_8_6/ext/etc/etc.txt.ja new file mode 100644 index 0000000000..2dddcfb036 --- /dev/null +++ b/ruby_1_8_6/ext/etc/etc.txt.ja @@ -0,0 +1,72 @@ +.\" etc.txt.ja - -*- Indented-Text -*- created at: Fri Jul 14 00:47:15 JST 1995 + +** Etc(モジュール) + +/etcディレクトリ以下の情報を得るためのモジュール.クラスにインクルード +して使うこともできる. + +Module Function: + + getlogin + + 自分のlogin名を返す.これが失敗した場合はgetpwuid()を用いると + 良い. + + getpwnam(name) + + /etc/passwdファイル(あるいはDBMファイルやNISデータベース)を検 + 索し,nameの名前を持つpasswdエントリを返す.戻り値はpasswd構造 + 体で以下のメンバを持つ. + + struct passwd + name # ユーザ名(文字列) + passwd # パスワード(文字列) + uid # ユーザID(整数) + gid # グループID(整数) + gecos # gecosフィールド(文字列) + dir # ホームディレクトリ(文字列) + shell # ログインシェル(文字列) + # 以降のメンバはシステムによっては提供されない. + change # パスワード変更時間(整数) + quota # クォータ(整数) + age # エージ(整数) + class # ユーザアクセスクラス(文字列) + comment # コメント(文字列) + expire # アカウント有効期限(整数) + end + + 詳細はgetpwnam(3)を参照のこと. + + getpwuid([uid]) + + uidをユーザIDとするpasswdエントリを返す.戻り値はgetpwnam()と + 同様である.引数を省略した場合にはgetuid()の値を用いる.詳細は + getpwuid(3)を参照のこと. + + getgrgid(gid) + + /etc/groupファイル(あるいは…getpwnam参照)を検索し,gidをグルー + プIDとするグループエントリを返す.戻り値はgroup構造体で以下の + メンバを持つ. + + struct group + name # グループ名(文字列) + passwd # グループのパスワード(文字列) + gid # グループID(整数) + mem # グループメンバ名の配列 + end + + 詳細はgetgrgid(3)を参照のこと. + + getgrnam(name) + + nameという名前のグループエントリを返す.戻り値はgetgrgid()と同 + 様である.詳細はgetgrnam(3)を参照. + + group + + 全てのグループエントリを順にアクセスするためのイテレータ. + + passwd + + 全てのpasswdエントリを順にアクセスするためのイテレータ. diff --git a/ruby_1_8_6/ext/etc/extconf.rb b/ruby_1_8_6/ext/etc/extconf.rb new file mode 100644 index 0000000000..dbd0672545 --- /dev/null +++ b/ruby_1_8_6/ext/etc/extconf.rb @@ -0,0 +1,43 @@ +require 'mkmf' + +have_library("sun", "getpwnam") # NIS (== YP) interface for IRIX 4 +a = have_func("getlogin") +b = have_func("getpwent") +c = have_func("getgrent") +if a or b or c + have_struct_member('struct passwd', 'pw_gecos', 'pwd.h') + have_struct_member('struct passwd', 'pw_change', 'pwd.h') + have_struct_member('struct passwd', 'pw_quota', 'pwd.h') + if have_struct_member('struct passwd', 'pw_age', 'pwd.h') + case what_type?('struct passwd', 'pw_age', 'pwd.h') + when "string" + f = "safe_setup_str" + when "long long" + f = "LL2NUM" + else + f = "INT2NUM" + end + $defs.push("-DPW_AGE2VAL="+f) + end + have_struct_member('struct passwd', 'pw_class', 'pwd.h') + have_struct_member('struct passwd', 'pw_comment', 'pwd.h') unless /cygwin/ === RUBY_PLATFORM + have_struct_member('struct passwd', 'pw_expire', 'pwd.h') + have_struct_member('struct passwd', 'pw_passwd', 'pwd.h') + have_struct_member('struct group', 'gr_passwd', 'grp.h') + [%w"uid_t pwd.h", %w"gid_t grp.h"].each do |t, *h| + h.unshift("sys/types.h") + f = "INT2NUM" + if have_type(t, h) + if try_static_assert("sizeof(#{t}) > sizeof(long)", h) + f = "LL2NUM" + end + if try_static_assert("(#{t})-1 > 0", h) + f = "U#{f}" + end + end + t = t.chomp('_t').upcase + $defs.push("-DPW_#{t}2VAL=#{f}") + $defs.push("-DPW_VAL2#{t}=#{f.sub(/([A-Z]+)2(NUM)/, '\22\1')}") + end + create_makefile("etc") +end |