--9amGYk9869ThD9tj
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Mon 12 Jan 2004 at 10:31:52 +0900, Yukihiro Matsumoto wrote:

> In message "Re: [PATCH] File.readable_world? and File.writable_world?"
>     on 04/01/12, Ian Macdonald <ian / caliban.org> writes:
> 
> |> I think it would be source of confusion.  They are too similar.  How
> |> about writable_world? returns its permission bits if the file is
> |> writable from others, otherwise nil?
> 
> |That's an interesting idea. The only problem is that world_writable?
> |would return nil when checking a file that has accidentally acquired,
> |for example, mode 446, which is very insecure. Returning nil in such a
> |case from a method with a name like world_writable? might also be
> |confusing.
> 
> The mode 446 is -r--r--rw-, which is writable from others, so that
> world_writable? should not return nil, right?

Here is a new patch that implements things the way you describe. I've
also attached a new ChangeLog.

> |What about Nobu's suggestion to have the methods in File::Stat, too? Do
> |you want me to add them there, also?
> 
> Sounds nice.

I'll wait for you to accept the first patch, if that's OK. Then, I'll
make a new patch with the additions to File::Stat.

Ian
-- 
Ian Macdonald               | For children with short attention spans:
System Administrator        | boomerangs that don't come back. 
ian / caliban.org             | 
http://www.caliban.org      | 
                            | 

--9amGYk9869ThD9tj
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ruby-1.8.1-File3.diff"

diff -uNr ruby-1.8.1.orig/ruby/file.c ruby-1.8.1/ruby/file.c
--- ruby-1.8.1.orig/ruby/file.c	2003-12-24 07:19:09.000000000 -0800
+++ ruby-1.8.1/ruby/file.c	2004-01-12 01:50:46.000000000 -0800
@@ -1015,6 +1015,50 @@
     return Qtrue;
 }
 
+/*
+ * call-seq:
+ *    File.world_readable?(file_name)   fixnum or nil
+ *
+ * If <i>file_name</i> is readable by others, returns an integer
+ * representing the file permission bits of <i>file_name</i>. Returns
+ * <code>nil</code> otherwise. The meaning of the bits is platform
+ * dependent; on Unix systems, see <code>stat(2)</code>.
+ *     
+ *    File.world_readable?("/etc/passwd")	    # 420
+ *    m  ile.world_readable?("/etc/passwd")
+ *    sprintf("%o", m)				    # "644"
+ */
+
+#ifndef S_IRUGO
+#  define S_IRUGO		(S_IRUSR | S_IRGRP | S_IROTH)
+#endif
+
+#ifndef S_IWUGO
+#  define S_IWUGO		(S_IWUSR | S_IWGRP | S_IWOTH)
+#endif
+
+static VALUE
+test_wr(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)) S_IROTH) {
+#ifdef __BORLANDC__
+      return UINT2NUM((unsigned short)(st.st_mode &
+				       (S_IRUGO|S_IWUGO|S_IXUGO)));
+#else
+      return UINT2NUM(st.st_mode & (S_IRUGO|S_IWUGO|S_IXUGO));
+#endif
+    }
+    else {
+      return Qnil;
+    }
+#endif
+    return Qfalse;
+}
 
 /*
  * call-seq:
@@ -1052,6 +1096,43 @@
 
 /*
  * call-seq:
+ *    File.world_writable?(file_name)   fixnum or nil
+ *
+ * If <i>file_name</i> is writable by others, returns an integer
+ * representing the file permission bits of <i>file_name</i>. Returns
+ * <code>nil</code> otherwise. The meaning of the bits is platform
+ * dependent; on Unix systems, see <code>stat(2)</code>.
+ *     
+ *    File.world_writable?("/tmp")		    #511
+ *    m  ile.world_writable?("/tmp")
+ *    sprintf("%o", m)				    #"777"
+ */
+
+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)) S_IWOTH) {
+#ifdef __BORLANDC__
+      return UINT2NUM((unsigned short)(st.st_mode &
+				       (S_IRUGO|S_IWUGO|S_IXUGO)));
+#else
+      return UINT2NUM(st.st_mode & (S_IRUGO|S_IWUGO|S_IXUGO));
+#endif
+    }
+    else {
+      return Qnil;
+    }
+#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 +4133,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("world_readable?", test_wr, 1);
     define_filetest_function("writable?", test_w, 1);
     define_filetest_function("writable_real?", test_W, 1);
+    define_filetest_function("world_writable?", 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);

--9amGYk9869ThD9tj
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=ChangeLog

Mon Jan 12 02:00:11 2004  Ian Macdonald  <ian / caliban.org>
	
	* file.c (test_wr, test_ww): New functions implementing new
	  methods (File::world_readable?, File::world_writable?).
	
	* file.c (S_IRUGO, S_IGUGO): New macros.
	
	* lib/pathname.rb: New methods (FileTest#world_readable?,
	  FileTest#world_writable?).

--9amGYk9869ThD9tj--