[prev in list] [next in list] [prev in thread] [next in thread] 

List:       ruby-core
Subject:    Patch to enable innetgr() & getnetgrent() suport in Etc
From:       "James F. Hranicky" <jfh () cise ! ufl ! edu>
Date:       2004-12-18 2:49:51
Message-ID: 20041217214729.4d1ff9c1.jfh () cise ! ufl ! edu
[Download RAW message or body]

Here's a patch to enable netgroup support in the Etc module. 
Etc.getnetgrents() can either take a block that iterates through
the members of a netgroup or return an array of the members. 
Etc.innetgr() returns true or false if the triplet in question is
a member of the netgroup.

As far as I can tell, these routines don't signal invalid netgroups
terribly well, although something could be hacked in.

Anyone interested in adding this? Feel free to modify anything 
to make it fit right.

----------------------------------------------------------------------
| Jim Hranicky, Senior SysAdmin                   UF/CISE Department |
| E314D CSE Building                            Phone (352) 392-1499 |
| jfh@cise.ufl.edu                      http://www.cise.ufl.edu/~jfh |
----------------------------------------------------------------------

["ruby-netgroup.patch" (text/plain)]

diff -ur ruby-1.8.2/ext/etc/etc.c ruby-1.8.2.mod/ext/etc/etc.c
--- ruby-1.8.2/ext/etc/etc.c	2003-11-24 05:42:17.000000000 -0500
+++ ruby-1.8.2.mod/ext/etc/etc.c	2004-12-17 16:36:31.569796000 -0500
@@ -23,7 +23,7 @@
 #include <grp.h>
 #endif
 
-static VALUE sPasswd, sGroup;
+static VALUE sPasswd, sGroup, sNetgroup;
 
 #ifndef _WIN32
 char *getenv();
@@ -359,6 +359,75 @@
     return Qnil;
 }
 
+#ifdef HAVE_GETNETGRENT
+
+static VALUE
+setup_netgroup(host, user, domain)
+    char *user, *host, *domain;
+{
+    return rb_struct_new(sNetgroup,
+            safe_setup_str(host),
+            safe_setup_str(user),
+            safe_setup_str(domain));
+}
+#endif
+
+static VALUE
+etc_innetgr(obj, netgroup, host, user, domain)
+    VALUE obj, netgroup, host, user, domain;
+{
+#ifdef HAVE_INNETGR
+    int ret;
+
+    SafeStringValue(netgroup);
+    SafeStringValue(host);
+    SafeStringValue(user);
+    SafeStringValue(domain);
+
+    ret = innetgr(RSTRING(netgroup)->ptr,
+            RSTRING(host)->ptr,
+            RSTRING(user)->ptr,
+            RSTRING(domain)->ptr);
+
+    return (ret == 1) ? Qtrue : Qfalse;
+#else
+    return Qnil;
+#endif
+}
+
+static VALUE
+etc_getnetgrents(obj, netgroup)
+    VALUE obj, netgroup;
+{
+#ifdef HAVE_GETNETGRENT
+    char *host, *user, *domain;
+    VALUE arr;
+
+    SafeStringValue(netgroup);
+    setnetgrent(RSTRING(netgroup)->ptr);
+
+    rb_secure(4);
+    if (!rb_block_given_p())
+        arr = rb_ary_new();
+
+    while (getnetgrent(&host, &user, &domain)) { 
+        if (rb_block_given_p()) {
+            rb_yield(setup_netgroup(host, user, domain));
+        } else { 
+            rb_ary_push(arr, setup_netgroup(host, user, domain));
+        }
+    }
+
+    if (!rb_block_given_p())
+        return arr;
+    else
+        return Qnil;
+#else
+    return Qnil;
+#endif
+}
+
+
 static VALUE mEtc;
 
 void
@@ -382,6 +451,9 @@
     rb_define_module_function(mEtc, "endgrent", etc_endgrent, 0);
     rb_define_module_function(mEtc, "getgrent", etc_getgrent, 0);
 
+    rb_define_module_function(mEtc, "innetgr", etc_innetgr, 4);
+    rb_define_module_function(mEtc, "getnetgrents", etc_getnetgrents, 1);
+
     sPasswd =  rb_struct_define("Passwd",
 				"name", "passwd", "uid", "gid",
 #ifdef HAVE_ST_PW_GECOS
@@ -409,6 +481,11 @@
 				NULL);
     rb_global_variable(&sPasswd);
 
+#ifdef HAVE_GETNETGRENT
+    sNetgroup = rb_struct_define("Netgroup", "user", "host", "domain", NULL);
+    rb_global_variable(&sNetgroup);
+#endif
+
 #ifdef HAVE_GETGRENT
     sGroup = rb_struct_define("Group", "name", "passwd", "gid", "mem", NULL);
     rb_global_variable(&sGroup);
diff -ur ruby-1.8.2/ext/etc/extconf.rb ruby-1.8.2.mod/ext/etc/extconf.rb
--- ruby-1.8.2/ext/etc/extconf.rb	2003-11-24 05:42:17.000000000 -0500
+++ ruby-1.8.2.mod/ext/etc/extconf.rb	2004-12-17 16:35:32.232131000 -0500
@@ -4,6 +4,8 @@
 a = have_func("getlogin")
 b = have_func("getpwent")
 c = have_func("getgrent")
+d = have_func("getnetgrent")
+d = have_func("innetgr")
 if  a or b or c
   have_struct_member('struct passwd', 'pw_gecos', 'pwd.h')
   have_struct_member('struct passwd', 'pw_change', 'pwd.h')


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic