--OwLcNYc0lM97+oe1
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hello,

As a system administrator, it's nice to be able to check for world
readable and writable files without having to File.stat the file and
check the mode for the relevant bits. Whilst that's easy enough to do,
the resulting code is too ugly for an elegant language like Ruby, IMHO.

The attached patch implements the File.readable_world? and
File.writable_world? methods. Please consider its inclusion in Ruby. The
diff is against the latest 1.8.1 snapshot.

Thanks,

Ian
-- 
Ian Macdonald               | In this world of sin and sorrow there is
System Administrator        | always something to be thankful for; as for
ian / caliban.org             | me, I rejoice that I am not a Republican.  
http://www.caliban.org      | -- H.L. Mencken 
                            | 

--OwLcNYc0lM97+oe1
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ruby-1.8.1-File.diff"

diff -uNr ruby.orig/file.c ruby/file.c
--- ruby.orig/file.c	2003-12-24 07:19:09.000000000 -0800
+++ ruby/file.c	2004-01-09 00:42:36.000000000 -0800
@@ -1015,6 +1015,25 @@
     return Qtrue;
 }
 
+/*
+ * call-seq:
+ *    File.readable_world?(file_name)   true or false
+ *
+ * Returns <code>true</code> if the named file is readable by anyone.
+ */
+
+static VALUE
+test_rw(obj, fname)
+    VALUE obj, fname;
+{
+#ifdef S_IROTH
+    struct stat st;
+
+    if (rb_stat(fname, &st) < 0) return Qfalse;
+    if (st.st_mode & S_IROTH) return Qtrue;
+#endif
+    return Qfalse;
+}
 
 /*
  * call-seq:
@@ -1052,6 +1071,26 @@
 
 /*
  * call-seq:
+ *    File.writable_world?(file_name)   true or false
+ *
+ * Returns <code>true</code> if the named file is writable by anyone.
+ */
+
+static VALUE
+test_ww(obj, fname)
+    VALUE obj, fname;
+{
+#ifdef S_IWOTH
+    struct stat st;
+
+    if (rb_stat(fname, &st) < 0) return Qfalse;
+    if (st.st_mode & S_IWOTH) return Qtrue;
+#endif
+    return Qfalse;
+}
+
+/*
+ * call-seq:
  *    File.executable?(file_name)   true or false
  *
  * Returns <code>true</code> if the named file is executable by the effective
@@ -4052,8 +4091,10 @@
     define_filetest_function("exists?", test_e, 1); /* temporary */
     define_filetest_function("readable?", test_r, 1);
     define_filetest_function("readable_real?", test_R, 1);
+    define_filetest_function("readable_world?", test_rw, 1);
     define_filetest_function("writable?", test_w, 1);
     define_filetest_function("writable_real?", test_W, 1);
+    define_filetest_function("writable_world?", test_ww, 1);
     define_filetest_function("executable?", test_x, 1);
     define_filetest_function("executable_real?", test_X, 1);
     define_filetest_function("file?", test_f, 1);
diff -uNr ruby.orig/lib/pathname.rb ruby/lib/pathname.rb
--- ruby.orig/lib/pathname.rb	2003-12-25 23:42:35.000000000 -0800
+++ ruby/lib/pathname.rb	2004-01-09 00:19:55.000000000 -0800
@@ -423,6 +423,7 @@
   def owned?() FileTest.owned?(@path) end
   def readable?() FileTest.readable?(@path) end
   def readable_real?() FileTest.readable_real?(@path) end
+  def readable_world?() FileTest.readable_world?(@path) end
   def setuid?() FileTest.setuid?(@path) end
   def setgid?() FileTest.setgid?(@path) end
   def size() FileTest.size(@path) end
@@ -431,6 +432,7 @@
   def symlink?() FileTest.symlink?(@path) end
   def writable?() FileTest.writable?(@path) end
   def writable_real?() FileTest.writable_real?(@path) end
+  def writable_world?() FileTest.writable_world?(@path) end
   def zero?() FileTest.zero?(@path) end
 end
 

--OwLcNYc0lM97+oe1--