tmail/amstd/fileutils.rb
#
# fileutils.rb
#
# Copyright (c) 2000 Minero Aoki
#
# This program is free software.
# You can distribute/modify this program under the terms of
# the GNU General Public License version 2 or later.
#
module FileUtilities
extend FileTest
Separator = File::ALT_SEPARATOR || File::SEPARATOR
module_function
def join( *args )
args.flatten!
args.join( Separator )
end
def cd( dn )
if iterator? then
pre = Dir.pwd
Dir.chdir dn
yield
Dir.chdir pre
else
Dir.chdir dn
end
end
alias chdir cd
def is_newer?( new, old )
return false unless exist? new
File.ctime(new) >= File.ctime(old)
end
alias uptodate? is_newer?
def is_older?( old, new )
return true unless exist? old
File.ctime(new) <= File.ctime(old)
end
def mkdir( dn )
return if directory? dn
Dir.mkdir dn
end
def mkdir_p( dn )
return if directory? dn
mkdir_p File.dirname dn
Dir.mkdir dn unless File.basename(dn) == ''
end
def ln( old, new )
dest = fu_make_dest_fname( old, new )
File.link old, dest
end
def ln_s( old, new )
dest = fu_make_dest_fname( old, new )
File.symlink old, new
end
BSIZE = 1024 * 2 # 2KB
def cp( from, to )
dest = fu_make_dest_fname( from, to )
rf = File.open( from ) ; rf.binmode
wf = File.open( dest, 'w' ); wf.binmode
s = nil
begin
while s = rf.sysread( BSIZE * 16 ) do
wf.syswrite s
end
rescue EOFError
ensure
rf.close
wf.close
end
end
def cp_r( from, to )
if directory? from then
from = File.expand_path(from)
do_cp_r File.dirname(from), File.basename(from), to
else
cp from, to
end
end
def do_cp_r( base, abs, to )
dirs = nil
Dir.open( join base, abs ) {|d| dirs = d.to_a }
dirs.each do |fn|
if directory? fn then
next if /\A\.\.?\z/o === fn
mkdir join(to, abs, fn)
do_cp_r base, join(abs, fn), to
else
cp join(base, abs, fn), join(to, abs, fn)
end
end
end
private_class_method :do_cp_r
def mv( from, to )
dest = fu_make_dest_fname( from, to )
st = File.stat( from )
if File::ALT_SEPARATOR then
File.unlink dest
end
begin
File.rename from, dest
rescue
if symlink? from then
File.symlink File.readlink(from), dest
File.unlink from
else
cp from, dest
File.unlink from
File.utime st.atime, st.mtime, dest
begin
File.chown st.uid, st.gid, dest
rescue
end
end
end
end
def rm( fn )
File.unlink fn
end
def rm_f( fn )
return unless exist? fn
unless file? fn then
futilsmsg "'rm -f #{fn}' fail: not file"
return
end
File.chmod 0777, fn
File.unlink fn
end
def rm_rf( *args )
args.flatten!
args.each do |i|
if directory? i then
do_rmrf i
else
rm_f i
end
end
end
def do_rmrf( dn )
Dir.foreach( dn ) do |fn|
next if /\A\.\.?\z/ === fn
fn = join( dn, fn )
if directory? fn then
do_rmrf fn
else
rm_f fn
end
end
Dir.rmdir dn
end
private_class_method :do_rmrf
def cmp( filea, fileb )
a = File.open( filea ); a.binmode
b = File.open( fileb ); b.binmode
stra = strb = ''
begin
while stra == strb do
stra = a.read( BSIZE )
strb = b.read( BSIZE )
unless stra and strb then
if stra.nil? and strb.nil? then
return true
end
end
end
rescue EOFError
;
ensure
a.close
b.close
end
false
end
def install( from, to, mode = nil )
dest = fu_make_dest_fname( from, to )
unless exist? dest and cmp( from, dest ) then
rm_f dest
cp from, dest
File.chmod mode, dest if mode
end
end
def fu_make_dest_fname( from, to )
if directory? to then
(to[-1,1] == Separator ? to : to + Separator) + File.basename(from)
else
to
end
end
private_class_method :fu_make_dest_fname
end