-
Notifications
You must be signed in to change notification settings - Fork 0
/
ftools.rb
166 lines (137 loc) · 3.23 KB
/
ftools.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
class << File
BUFSIZE = 8 * 1024
def catname from, to
if FileTest.directory? to
File.join to.sub(%r([/\\]$), ''), basename(from)
else
to
end
end
# copy file
def syscopy from, to
to = catname(from, to)
fmode = stat(from).mode
tpath = to
not_exist = !exist?(tpath)
from = open(from, "rb")
to = open(to, "wb")
begin
while true
to.syswrite from.sysread(BUFSIZE)
end
rescue EOFError
ret = true
rescue
ret = false
ensure
to.close
from.close
end
chmod(fmode, tpath) if not_exist
ret
end
def copy from, to, verbose = false
$deferr.print from, " -> ", catname(from, to), "\n" if verbose
syscopy from, to
end
alias cp copy
# move file
def move from, to, verbose = false
to = catname(from, to)
$deferr.print from, " -> ", to, "\n" if verbose
if RUBY_PLATFORM =~ /djgpp|(cyg|ms|bcc)win|mingw/ and FileTest.file? to
unlink to
end
fstat = stat(from)
begin
rename from, to
rescue
begin
symlink File.readlink(from), to and unlink from
rescue
from_stat = stat(from)
syscopy from, to and unlink from
utime(from_stat.atime, from_stat.mtime, to)
begin
chown(fstat.uid, fstat.gid, to)
rescue
end
end
end
end
alias mv move
# compare two files
# true: identical
# false: not identical
def compare from, to, verbose = false
$deferr.print from, " <=> ", to, "\n" if verbose
return false if stat(from).size != stat(to).size
from = open(from, "rb")
to = open(to, "rb")
ret = false
fr = tr = ''
begin
while fr == tr
fr = from.read(BUFSIZE)
if fr
tr = to.read(fr.size)
else
ret = to.read(BUFSIZE)
ret = !ret || ret.length == 0
break
end
end
rescue
ret = false
ensure
to.close
from.close
end
ret
end
alias cmp compare
# unlink files safely
def safe_unlink(*files)
verbose = if files[-1].is_a? String then false else files.pop end
begin
$deferr.print files.join(" "), "\n" if verbose
chmod 0777, *files
unlink(*files)
rescue
# $deferr.print "warning: Couldn't unlink #{files.join ' '}\n"
end
end
alias rm_f safe_unlink
def makedirs(*dirs)
verbose = if dirs[-1].is_a? String then false else dirs.pop end
# mode = if dirs[-1].is_a? Fixnum then dirs.pop else 0755 end
mode = 0755
for dir in dirs
parent = dirname(dir)
next if parent == dir or FileTest.directory? dir
makedirs parent unless FileTest.directory? parent
$deferr.print "mkdir ", dir, "\n" if verbose
if basename(dir) != ""
Dir.mkdir dir, mode
end
end
end
alias mkpath makedirs
alias o_chmod chmod
vsave, $VERBOSE = $VERBOSE, false
def chmod(mode, *files)
verbose = if files[-1].is_a? String then false else files.pop end
$deferr.printf "chmod %04o %s\n", mode, files.join(" ") if verbose
o_chmod mode, *files
end
$VERBOSE = vsave
def install(from, to, mode = nil, verbose = false)
to = catname(from, to)
unless FileTest.exist? to and cmp from, to
safe_unlink to if FileTest.exist? to
cp from, to, verbose
chmod mode, to, verbose if mode
end
end
end
# vi:set sw=2: