filesystem-0.5004075500007650000024000000000000753057141000121675ustar00mghstafffilesystem-0.5/dfrb010075500007650000024000000012400746310671000131050ustar00mghstaff#!/usr/local/bin/ruby require 'filesystem' def pct(total, avail) (total == 0) ? 0 : (100.0 * avail / total).round end FMT = "%-10s %8d %8d %3d %8d %8d %3d" HDR = "Mount KB Avail %free Files Avail %free" def df(mnt) puts HDR if mnt.size > 0 mnt.sort.each do |m| s = FileSystem.stat m bpct = pct(s.blocks, s.blocks_avail) fpct = pct(s.files, s.files_avail) puts format(FMT, m, s.blocks, s.blocks_avail, bpct, s.files, s.files_avail, fpct) end end def mounted mts = [] FileSystem.mounts.each {|m| mts << m.mount if m.device =~ %r(/dev/)} mts end df ((ARGV.size == 0) ? mounted : ARGV) filesystem-0.5/extconf.rb010064400007650000024000000001210745757717200142530ustar00mghstaffrequire 'mkmf' have_header 'sys/mnttab.h' # Solaris create_makefile 'filesystem' filesystem-0.5/filesystem.c010064400007650000024000000074250772600532200146040ustar00mghstaff/* * filesystem.c * * Ruby extension for 'statvfs' and 'getmntent' system calls * Mike Hall www.enteract.com/~mghall 2002-04-24 * * Tested on Linux and Solaris */ #include "ruby.h" #include #include #include #ifdef HAVE_SYS_MNTTAB_H /* Solaris */ #include #define MNTENT mnttab #define START_MNT(F,M) fopen(F,M) #define GET_MNT(FP,MP) (getmntent(FP,MP) == 0) #define END_MNT(F) fclose(F) #define MOUNTLIST "/etc/mnttab" #else /* GNU, Linux, (and BSDs?) */ #include #define MNTENT mntent #define START_MNT(F,M) setmntent(F,M) #define GET_MNT(FP,MP) ((MP = getmntent(FP)) != NULL) #define END_MNT(F) endmntent(F) #define MOUNTLIST "/etc/mtab" #endif VALUE mfs, sFSstat, sFSmount; static VALUE setup_mount(struct MNTENT *mp) { return rb_struct_new(sFSmount, #ifdef HAVE_SYS_MNTTAB_H rb_tainted_str_new2(mp->mnt_special), rb_tainted_str_new2(mp->mnt_mountp), rb_tainted_str_new2(mp->mnt_fstype), rb_tainted_str_new2(mp->mnt_mntopts), rb_tainted_str_new2(mp->mnt_time) #else rb_tainted_str_new2(mp->mnt_fsname), rb_tainted_str_new2(mp->mnt_dir), rb_tainted_str_new2(mp->mnt_type), rb_tainted_str_new2(mp->mnt_opts), INT2NUM(mp->mnt_freq), INT2NUM(mp->mnt_passno) #endif ); } static VALUE fs_mounts(int argc, VALUE *argv, VALUE obj) { VALUE x, res; FILE *fp; char *tab; struct MNTENT *mp; #ifdef HAVE_SYS_MNTTAB_H struct MNTENT mt; mp = &mt; #endif if ( rb_scan_args(argc, argv, "01", &x) == 1 ) { tab = STR2CSTR(x); } else { tab = MOUNTLIST; } fp = START_MNT(tab, "r"); if ( fp == NULL ) { rb_sys_fail(tab); } if ( rb_block_given_p() ) { res = obj; while ( GET_MNT(fp, mp) ) { rb_yield( setup_mount(mp) ); } } else { res = rb_ary_new(); while ( GET_MNT(fp, mp) ) { rb_ary_push(res, setup_mount(mp)); } } END_MNT(fp); return res; } static VALUE fs_stat(VALUE obj, VALUE dir) { struct statvfs fs; char *s = STR2CSTR(dir); if ( statvfs(s, &fs) < 0 ) { rb_sys_fail(s); } return rb_struct_new(sFSstat, dir, INT2NUM(fs.f_bsize), INT2NUM(fs.f_blocks), INT2NUM(fs.f_bfree), INT2NUM(fs.f_bavail), INT2NUM(fs.f_files), INT2NUM(fs.f_ffree), INT2NUM(fs.f_favail), INT2NUM(fs.f_flag), INT2NUM(fs.f_namemax), 0 ); } void Init_filesystem() { mfs = rb_define_module("FileSystem"); rb_define_module_function(mfs, "stat", fs_stat, 1); rb_define_module_function(mfs, "mounts", fs_mounts, -1); sFSstat = rb_struct_define("FileSystemStat", "path", "block_size", "blocks", "blocks_free", "blocks_avail", "files", "files_free", "files_avail", "flags", "maxnamelen", 0); rb_global_variable(&sFSstat); sFSmount = rb_struct_define("FileSystemMount", "device", "mount", "fstype", "options", #ifdef HAVE_SYS_MNTTAB_H "time", #else "dump_interval", "check_pass", #endif 0); rb_global_variable(&sFSmount); #ifdef ST_RDONLY rb_define_const(mfs, "RDONLY", INT2FIX(ST_RDONLY)); #endif #ifdef ST_NOSUID rb_define_const(mfs, "NOSUID", INT2FIX(ST_NOSUID)); #endif #ifdef ST_NOTRUNC rb_define_const(mfs, "NOTRUNC", INT2FIX(ST_NOTRUNC)); #endif #ifdef ST_NODEV rb_define_const(mfs, "NODEV", INT2FIX(ST_NODEV)); #endif #ifdef ST_NOEXEC rb_define_const(mfs, "NOEXEC", INT2FIX(ST_NOEXEC)); #endif #ifdef ST_SYNCHRONOUS rb_define_const(mfs, "SYNC", INT2FIX(ST_SYNCHRONOUS)); #endif #ifdef ST_MANDLOCK rb_define_const(mfs, "MANDLOCK", INT2FIX(ST_MANDLOCK)); #endif #ifdef ST_WRITE rb_define_const(mfs, "WRITE", INT2FIX(ST_WRITE)); #endif #ifdef ST_APPEND rb_define_const(mfs, "APPEND", INT2FIX(ST_APPEND)); #endif #ifdef ST_IMMUTABLE rb_define_const(mfs, "IMMUTABLE", INT2FIX(ST_IMMUTABLE)); #endif #ifdef ST_NOATIME rb_define_const(mfs, "NOATIME", INT2FIX(ST_NOATIME)); #endif #ifdef ST_NODIRATIME rb_define_const(mfs, "NODIRATIME", INT2FIX(ST_NODIRATIME)); #endif } filesystem-0.5/FileSystem.html010064400007650000024000000110530753057136600152270ustar00mghstaff DESCRIPTION
This is a Ruby extension for file-system information, using the statvfs and getmntent system calls. Tested on Linux and Solaris Version 0.3


MODULE

require 'filesystem'
FileSystem.stat( path )
Struct FileSystemStat
 
s.path directory path provided
s.block_size optimal transfer block size
s.blocks total number of data blocks in file system
s.blocks_free number of free blocks in file system
s.blocks_avail number of free blocks available to non-super-user
s.files total number of file nodes in file system
s.files_free number of free file nodes in file system
s.files_avail number of free file nodes available to non-super-user
s.flags file system flags
s.maxnamelen maximum file name length

FileSystem.mounts( file )
FileSystem.mounts( file ) { |mt| block }

The default mount-table filename is /etc/mtab on Linux, and /etc/mnttab on Solaris. On Linux, this can be used to scan /etc/fstab also.

Struct FileSystemMount
 
m.device file system (i.e. partition device) name
m.mount mount point directory
m.fstype file system type m.options mount options
m.time time the filesystem was mounted (Solaris)
m.dump_interval dump frequency in days (Linux/BSD)
m.check_pass pass number of file system check (Linux/BSD)

Constants for FileSystem.stat.flags

  • Solaris: RDONLY NOSUID NOTRUNC
  • Linux: RDONLY NOSUID
  • GNU: RDONLY NOSUID NODEV NOEXE SYNC MANDLOCK WRITE APPEND IMMUTABLE NOATIME NODIRATIME


EXAMPLES

require 'filesystem'
s = FileSystem.stat '/tmp'
puts "#{s.path} #{s.blocks_avail}"

puts "Mounted FileSystems:"
FileSystem.mounts.each do |m|
    puts "#{m.device} #{m.mount} #{m.fstype}"
end


INSTALL

ruby extconf.rb
make
ruby Test.rb (optional directories)
make install


DOCUMENTATION

The  FileSystem.ri file is a source description file for the ri command. Copy it to your ri/srcdesc source directory as FileSystem.rb, and regenerate the binary description files that ri uses. See the ri  README for details.


TODO

  • Move this "documentation" into the source.
  • Convert st.flags from a number to an array of strings.
  • Solicit patches for all other UNIXes.


ACKNOWLEDGEMENTS

Daniel Berger for testing on Solaris, and motivation.
comp.lang.ruby for suggesting better names.


AUTHOR

Mike Hall
mghall@enteract.com
www.enteract.com/~mghall
2002-05-02
filesystem-0.5/FileSystem.rd010064400007650000024000000076420753057140200146700ustar00mghstaff=begin = FileSystem *Version: 0.03 *Date: 2002-05-02 *Author: Mike Hall *e-mail: mghall@enteract.com *Home Page: (()) == Preface This is a simple extension to get file-system information from the operating system. It uses the 'statvfs' and 'getmntent' routines on Linux and Solaris. == Module Description * FileSystem * FileSystem.mounts Several calling formats: FileSystem.mounts returns array describing currenly mounted filesystem FileSystem.mounts "filename" returns array of filesystem descriptions from given file FileSystem.mounts {|m| block } invokes block for each mounted filesystem FileSystem.mounts("filename") {|m| block} invokes block for each filesystem described in the file The default mount-table filename is "/etc/mtab" on Linux, and "/etc/mnttab" on Solaris. On Linux, FileSystem.mounts can be used to scan "/etc/fstab" also. * FileSystemMount Structure * m.device file system (i.e. partition device) name * m.mount mount point directory * m.fstype file system type * m.options mount options * m.time time the filesystem was mounted (Solaris) * m.dump_interval dump frequency in days (Linux/BSD) * m.check_pass pass number of file system check (Linux/BSD) * FileSystem.stat One invocation: FileSystem.stat "path" returns structure describing the designated filesystem * FileSystemStat Structure * s.path directory path provided * s.block_size optimal transfer block size * s.blocks total number of data blocks in file system * s.blocks_free number of free blocks in file system * s.blocks_avail number of free blocks available to non-super-user * s.files total number of file nodes in file system * s.files_free number of free file nodes in file system * s.files_avail number of free file nodes available to non-super-user * s.flags file system flags * s.maxnamelen maximum file name length * Constants for FileSystemStat.flags * Solaris: RDONLY NOSUID NOTRUNC * Linux: RDONLY NOSUID * GNU: RDONLY NOSUID NODEV NOEXE SYNC MANDLOCK WRITE APPEND IMMUTABLE NOATIME NODIRATIME == Installation (1) Unpack this archive (1) ruby extconf.rb (1) make (1) ruby Test.rb (1) ruby dfrb (1) make install == Usage and Samples Simple usage: # get an array of mounted filesystems mts = FileSystem.mounts # get the status of one filesystem s = FileSystem.stat '/tmp' A larger example, simulating the 'df' command: require 'filesystem' def pct(total, avail) (total == 0) ? 0 : (100.0 * avail / total).round end FMT = "%-10s %8d %8d %3d %8d %8d %3d" HDR = "Mount KB Avail %free Files Avail %free" def df(mnt) puts HDR if mnt.size > 0 mnt.sort.each do |m| s = FileSystem.stat m bpct = pct(s.blocks, s.blocks_avail) fpct = pct(s.files, s.files_avail) puts format(FMT, m, s.blocks, s.blocks_avail, bpct, s.files, s.files_avail, fpct) end end def mounted mts = [] FileSystem.mounts.each {|m| mts << m.mount if m.device =~ %r(/dev/)} mts end df ((ARGV.size == 0) ? mounted : ARGV) == Documentation * The README file * The 'FileSystem.html' file * This RDOC file, 'FileSystem.rd' * The 'FileSystem.ri' file is a source description for the 'ri' command. Copy if to your 'ri/srcdesc' source directory as 'FileSystem.rb', and regenerate the binary description files that 'ri' uses. See the 'ri' 'README' file for details. == To-Do * Convert 'st.flags' from a number to an array of strings * Get patches/fixes for other UNIX systems == Acknowledgements * Daniel Berger for testing on Solaris, and motivation. * comp.lang.ruby for suggesting better names. == Reference * 'statvfs' system call * 'getmntent' library routine =end filesystem-0.5/FileSystem.ri010064400007650000024000000052740753057141000146730ustar00mghstaff# Not automatically generated.... raise 'Must be invoked by installation process' unless $opfile # ----------------------------------------- aClass = ClassModule.new("FileSystem", "", "module") aClass.addFragment(Paragraph.new("The FileSystem module provides information about mounted file-systems.\n")) aClass.addFragment(Verbatim.new(" require 'filesystem'\n FileSystem.mounts.each {|m|\n s = FileSystem.stat m.mount\n puts \"\#\{m.mount} \#\{s.blocks_avail}\"\n }\n")) m0001 = MethodDesc.new("mounts", "class", "FileSystem.mounts( optional_file_name) -> array\nFileSystem.mounts( optional_file_name ) { |mt| optional block } "); m0001.addFragment(Paragraph.new("Returns an array of FileSystemMount structures, describing the mounted filesystems.\n")) m0001.addFragment(Paragraph.new("The default mount-table filename is /etc/mtab on Linux, and /etc/mnttab on Solaris. On Linux, this method can scan /etc/fstab also.\n")) m0001.addFragment(Paragraph.new("The members of the Mount structure are: device - filesystem device name; mount - mount point path; fstype - filesystem type; options - mount options; time - time when the filesystem was mounted (Solaris); dump_interval - days between dumps (Linux); check_pass - pass number of filesystem check (Linux);")) aClass.addMethod(m0001) m0002 = MethodDesc.new("stat", "class", "FileSystem.stat(path) -> array"); m0002.addFragment(Paragraph.new("Returns a FileSystemStat structure describing the filesystem containing the given file path.\n")) m0002.addFragment(Paragraph.new("The members of the Stat structure are: path - directory path provided; block_size - optimal transfer block size; blocks - total number of data blocks in file system; blocks_free - number of free blocks in file system; blocks_avail - number of free blocks available to non-super-user; files - total number of file nodes in file system; files_free - number of free file nodes in file system; files_avail - number of free file nodes available to non-super-user; flags - file system flags; maxnamelen - maximum file name length")) m0002.addFragment(Paragraph.new("The module defines the following constants for the Stat.flags member:\n RDONLY, NOSUID, NOTRUNC, NODEV, NOEXE, SYNC, MANDLOCK, WRITE, APPEND, IMMUTABLE, NOATIME, NODIRATIME.\n Not all constants are available on all platforms.")) aClass.addMethod(m0002) File.open($opfile, "w") {|f| Marshal.dump(aClass, f) } filesystem-0.5/Makefile010064400007650000024000000050570753057111600137150ustar00mghstaffSHELL = /bin/sh #### Start of system configuration section. #### srcdir = . topdir = $(rubylibdir)/$(arch) hdrdir = $(rubylibdir)/$(arch) VPATH = $(srcdir) CC = gcc CFLAGS = -fPIC -g -O2 CPPFLAGS = -I. -I$(hdrdir) -I$(srcdir) CXXFLAGS = $(CFLAGS) DLDFLAGS = -L$(rubylibdir)/$(arch) -L$(exec_prefix)/lib LDSHARED = gcc -shared LIBPATH = RUBY_INSTALL_NAME = ruby RUBY_SO_NAME = arch = i686-linux ruby_version = 1.7 prefix = $(DESTDIR)/usr/local exec_prefix = $(prefix) bindir = $(exec_prefix)/bin sitelibdir = $(sitedir)/$(ruby_version) datadir = $(prefix)/share sitedir = $(prefix)/lib/ruby/site_ruby sharedstatedir = $(prefix)/com archdir = $(rubylibdir)/$(arch) localstatedir = $(prefix)/var infodir = $(prefix)/info oldincludedir = $(DESTDIR)/usr/include libexecdir = $(exec_prefix)/libexec compile_dir = $(DESTDIR)/opt/ruby/misc/ruby sbindir = $(exec_prefix)/sbin includedir = $(prefix)/include sysconfdir = $(prefix)/etc sitearchdir = $(sitelibdir)/$(arch) mandir = $(prefix)/man libdir = $(exec_prefix)/lib rubylibdir = $(libdir)/ruby/$(ruby_version) target_prefix = #### End of system configuration section. #### LOCAL_LIBS = LIBS = $(LIBRUBY_A) -lc OBJS = filesystem.o TARGET = filesystem DLLIB = $(TARGET).so RUBY = ruby RM = $(RUBY) -rftools -e "File::rm_f(*ARGV.map do|x|Dir[x]end.flatten.uniq)" MAKEDIRS = $(RUBY) -r ftools -e 'File::makedirs(*ARGV)' INSTALL_PROG = $(RUBY) -r ftools -e 'File::install(ARGV[0], ARGV[1], 0555, true)' INSTALL_DATA = $(RUBY) -r ftools -e 'File::install(ARGV[0], ARGV[1], 0644, true)' EXEEXT = all: $(DLLIB) clean: @$(RM) *.o *.so *.sl *.a $(DLLIB) @$(RM) $(TARGET).lib $(TARGET).exp $(TARGET).ilk *.pdb $(CLEANFILES) distclean: clean @$(RM) Makefile extconf.h conftest.* mkmf.log @$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) realclean: distclean install: $(archdir)$(target_prefix)/$(DLLIB) site-install: $(sitearchdir)$(target_prefix)/$(DLLIB) $(archdir)$(target_prefix)/$(DLLIB): $(DLLIB) @$(MAKEDIRS) $(rubylibdir) $(archdir)$(target_prefix) @$(INSTALL_PROG) $(DLLIB) $(archdir)$(target_prefix)/$(DLLIB) $(sitearchdir)$(target_prefix)/$(DLLIB): $(DLLIB) @$(MAKEDIRS) $(sitearchdir)$(target_prefix) @$(INSTALL_PROG) $(DLLIB) $(sitearchdir)$(target_prefix)/$(DLLIB) install: site-install: .cc.o: $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< .cpp.o: $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< .cxx.o: $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< .C.o: $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $< $(DLLIB): $(OBJS) $(LDSHARED) $(DLDFLAGS) -o $(DLLIB) $(OBJS) $(LIBS) $(LOCAL_LIBS) filesystem-0.5/MANIFEST010064400007650000024000000001300746425342200133740ustar00mghstaffREADME dfrb extconf.rb filesystem.c FileSystem.html FileSystem.ri FileSystem.rd Test.rb filesystem-0.5/README010064400007650000024000000043000772600544400131260ustar00mghstaff DESCRIPTION This is a Ruby extension for file-system information, using the 'statvfs' and 'getmntent' system calls. Tested on Linux and Solaris Version 0.5 MODULE module FileSystem FileSystem.stat( path ) Struct FileSystemStat s.path directory path provided s.block_size optimal transfer block size s.blocks total number of data blocks in file system s.blocks_free number of free blocks in file system s.blocks_avail number of free blocks available to non-super-user s.files total number of file nodes in file system s.files_free number of free file nodes in file system s.files_avail number of free file nodes available to non-super-user s.flags file system flags s.maxnamelen maximum file name length FileSystem.mounts( optional file name ) FileSystem.mounts( optional file name ) { |mt| optional block } The default mount-table filename is "/etc/mtab" on Linux, and "/etc/mnttab" on Solaris. On Linux, this can be used to scan "/etc/fstab" also. Struct FileSystemMount m.device file system (i.e. partition device) name m.mount mount point directory m.fstype file system type m.options mount options m.time time the filesystem was mounted (Solaris) m.dump_interval dump frequency in days (Linux/BSD) m.check_pass pass number of file system check (Linux/BSD) Constants for FileSystem.stat 'flags' Solaris: RDONLY NOSUID NOTRUNC Linux: RDONLY NOSUID GNU: RDONLY NOSUID NODEV NOEXE SYNC MANDLOCK WRITE APPEND IMMUTABLE NOATIME NODIRATIME INSTALL ruby extconf.rb make ruby Test.rb (optional directories) make install DOCUMENTATION The file 'FileSystem.ri' is a source description file for the 'ri' command. Copy it to your 'ri/srcdesc' source directory as 'FileSystem.rb', and regenerate the binary description files that 'ri' uses. See the 'ri' 'README' for details. TODO Move this "documentation" into the source. Convert st.flags from a number to an array of strings. Solicit patches for other UNIXen. ACKNOWLEDGEMENTS Daniel Berger for testing on Solaris, and motivation. comp.lang.ruby for suggesting better names. Dmitry Borodaenko for finding a bug (by testing on IA64 Debian) AUTHOR Mike Hall mghall@enteract.com www.enteract.com/~mghall 2003-09-04 filesystem-0.5/Test.rb010064400007650000024000000010370751563341000135120ustar00mghstaff require 'filesystem' ARGV.push '/tmp' if ARGV.empty? ARGV.each {|d| s = FileSystem.stat d puts "#{s.path} #{s.blocks_avail}" } begin bad = FileSystem.stat '/nono' rescue puts "Got error with '/nono', good!" end puts "Mounted FileSystems:" mts = FileSystem.mounts mts.each {|m| puts "#{m.device} #{m.mount} #{m.fstype}\n" } puts "Available FileSystems:" ['/etc/fstab', '/etc/vfstab', '/etc/mnttab'].each do |fst| if FileTest.exist?(fst) puts "In #{fst}:" FileSystem.mounts(fst) {|m| puts m.mount} break end end