--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--