qdumpfs 0.6.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/Gemfile.lock +3 -3
- data/README.md +22 -16
- data/data/from/0.txt +1 -0
- data/data/from/a/1.txt +1 -0
- data/exe/sample +40 -0
- data/lib/qdumpfs.rb +69 -129
- data/lib/qdumpfs/option.rb +19 -8
- data/lib/qdumpfs/util.rb +16 -12
- data/lib/qdumpfs/version.rb +4 -3
- data/run_list.sh +5 -0
- data/run_qdumpfs.sh +1 -1
- data/sample.sh +5 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7e95debed71b63b553da2ee5d9f4bb7828a855c1ed76a20188821fc507222f0
|
4
|
+
data.tar.gz: 31272461b61233cc082f9b44370eb3304415ac8025b67d8a13900795ead68570
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7419e48fea0c72b06d7c810ae22cf6c12f78aa4e9bcce21ffeeba176eafd039836169b178c0a13f892ca3834f687ea0a271b811311e6bf4904917a15a315ebf9
|
7
|
+
data.tar.gz: 1e596cb96545f92477e8695fd77394aba619afc928176a2d0f505914c25d1215e1eeda648a7673d10794460ea4521cb93933fe1303313b08aa7660d25d8ccb2f
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
# Qdumpfs
|
2
2
|
|
3
|
-
|
3
|
+
pdumpfsの個人的改良版です。
|
4
4
|
|
5
|
-
|
5
|
+
Gem化して最近のバージョンのバージョンのRubyに対応。コマンドの拡張などを行っています。
|
6
6
|
|
7
|
-
|
7
|
+
## インストール
|
8
8
|
|
9
|
-
|
9
|
+
gem install qdumpfs
|
10
10
|
|
11
|
+
## 使用方法
|
11
12
|
|
12
13
|
```
|
13
14
|
Usage: qdumpfs [options] <source> <dest>
|
@@ -19,48 +20,53 @@ Options
|
|
19
20
|
-e, --exclude=PATTERN exclude files/directories matching PATTERN
|
20
21
|
-s, --exclude-by-size=SIZE exclude files larger than SIZE
|
21
22
|
-w, --exclude-by-glob=GLOB exclude files matching GLOB
|
22
|
-
-c, --command=COMMAND backup|sync|list|expire|verify|
|
23
|
+
-c, --command=COMMAND backup|sync|list|expire|verify|delete
|
23
24
|
-l, --limit=HOURS limit hours
|
24
25
|
-k, --keep=KEEPARG ex: --keep 100Y12M12W30D (100years, 12months, 12weeks, 30days, default)
|
25
26
|
```
|
26
27
|
|
27
|
-
##
|
28
|
+
## 実行例
|
29
|
+
|
30
|
+
|
31
|
+
バックアップを実行する場合。
|
28
32
|
|
29
|
-
Backup your home directory, run the following command.
|
30
33
|
```
|
31
34
|
qdumpfs /home/foo /backup
|
32
35
|
```
|
33
36
|
|
34
|
-
|
37
|
+
"--command backup"オプションを明示することもできます。
|
38
|
+
|
35
39
|
```
|
36
40
|
qdumpfs --command=backup /home/foo /backup
|
37
41
|
```
|
38
42
|
|
39
|
-
|
43
|
+
"--command sync"でバックアップフォルダを同期できます。
|
40
44
|
```
|
41
45
|
qdumpfs --command=sync /backup1 /backup2
|
42
46
|
```
|
43
47
|
|
44
|
-
|
48
|
+
バックアップフォルダの同期には膨大な時間が必要な場合があるため、実行時間を制限できます。以下は例えば1時間に制限する場合です。
|
45
49
|
```
|
46
50
|
qdumpfs --command=sync --limit=1 /backup1 /backup2
|
47
51
|
```
|
48
52
|
|
49
|
-
|
53
|
+
バックアップフォルダの同期で、1時間でかつ"100Y12M12W30D"を保存する場合のオプションです。
|
50
54
|
```
|
51
|
-
qdumpfs --command=sync --limit=1 --keep=5Y6M7W10D
|
55
|
+
qdumpfs --command=sync --limit=1 --keep=5Y6M7W10D backup1 /backup2
|
52
56
|
```
|
53
57
|
|
54
|
-
|
58
|
+
"--command expire"で、"--keep="パターンに該当しないバックアップを削除できます。
|
55
59
|
```
|
56
|
-
qdumpfs --command=expire --limit=1 --keep=5Y6M7W10D
|
60
|
+
qdumpfs --command=expire --limit=1 --keep=5Y6M7W10D backup1 /backup2
|
57
61
|
```
|
58
62
|
|
63
|
+
"--command delete"で、バックアップに存在する指定したパスを削除できます(間違えてバックアップした内容を削除したい場合などに使用)。
|
64
|
+
```
|
65
|
+
qdumpfs --command=delete --delete-dir=backup1 --limit=1 r:/backup2
|
66
|
+
```
|
59
67
|
|
60
68
|
## License
|
61
69
|
|
62
70
|
qdumpfs is a free software with ABSOLUTELY NO WARRANTY under the terms of the GNU General Public License version 2.
|
63
71
|
|
64
72
|
|
65
|
-
|
66
|
-
|
data/data/from/0.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0
|
data/data/from/a/1.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1
|
data/exe/sample
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require "qdumpfs"
|
5
|
+
|
6
|
+
from = "./data/from"
|
7
|
+
to = "./data/to"
|
8
|
+
to2 = "./data/to2"
|
9
|
+
|
10
|
+
def create_dir(dir)
|
11
|
+
if FileTest.directory?(dir)
|
12
|
+
FileUtils.rm_rf(dir)
|
13
|
+
end
|
14
|
+
FileUtils.mkpath(dir)
|
15
|
+
end
|
16
|
+
|
17
|
+
create_dir(to)
|
18
|
+
create_dir(to2)
|
19
|
+
|
20
|
+
|
21
|
+
arg = ["--backup-at=20210119", from, to]
|
22
|
+
Qdumpfs::Command.run(arg)
|
23
|
+
arg = ["--backup-at=20210121", from, to]
|
24
|
+
Qdumpfs::Command.run(arg)
|
25
|
+
arg = ["--backup-at=20210122", from, to]
|
26
|
+
Qdumpfs::Command.run(arg)
|
27
|
+
arg = ["--backup-at=20210123", from, to]
|
28
|
+
Qdumpfs::Command.run(arg)
|
29
|
+
arg = ["--backup-at=20210124", from, to]
|
30
|
+
Qdumpfs::Command.run(arg)
|
31
|
+
|
32
|
+
|
33
|
+
arg = ["--backup-at=20210122", from, to2]
|
34
|
+
Qdumpfs::Command.run(arg)
|
35
|
+
arg = ["--backup-at=20210123", from, to2]
|
36
|
+
|
37
|
+
arg = ["--command=delete", "--delete-from=20210122", "--delete-to=20210123", "--limit=1", to, to2]
|
38
|
+
Qdumpfs::Command.run(arg)
|
39
|
+
|
40
|
+
|
data/lib/qdumpfs.rb
CHANGED
@@ -38,15 +38,22 @@ module Qdumpfs
|
|
38
38
|
opt.on('-c COMMAND', '--command=COMMAND', commands, commands.join('|')) {|v| opts[:c] = v}
|
39
39
|
opt.on('-l HOURS', '--limit=HOURS', 'limit hours') {|v| opts[:limit] = v}
|
40
40
|
opt.on('-k KEEPARG', '--keep=KEEPARG', 'ex: --keep 100Y12M12W30D (100years, 12months, 12weeks, 30days, default)') {|v| opts[:keep] = v}
|
41
|
-
opt.on('--logdir
|
42
|
-
opt.on('--delete-from
|
41
|
+
opt.on('--logdir=LOGDIR', 'logdir') {|v| opts[:logdir] = v}
|
42
|
+
opt.on('--delete-from=YYYYMMDD', 'delete backup from YYYY/MM/DD') {|v|
|
43
43
|
opts[:delete_from] = Date.parse(v)
|
44
44
|
}
|
45
|
-
opt.on('--delete-to
|
45
|
+
opt.on('--delete-to=YYYYMMDD', 'delete backup to YYYY/MM/DD') {|v|
|
46
46
|
opts[:delete_to] = Date.parse(v)
|
47
|
-
}
|
47
|
+
}
|
48
|
+
opt.on('--delete-dir=DIRS', 'relative path from the snapshot root of the backup. ex: --delete-dir=foo,home/bar') {|v|
|
49
|
+
opts[:delete_dirs] = v.split(/,/)
|
50
|
+
}
|
51
|
+
opt.on('--backup-at=YYYYMMDD', 'backup at YYYY/MM/DD') {|v|
|
52
|
+
opts[:backup_at] = Date.parse(v)
|
53
|
+
}
|
54
|
+
opt.on('-d', '--debug', 'debug mode') {|v| opts[:d] = v }
|
48
55
|
opt.parse!(argv)
|
49
|
-
option = Option.new(opts,
|
56
|
+
option = Option.new(opts, argv)
|
50
57
|
if opts[:v]
|
51
58
|
puts "<<<<< qdumpfs options >>>>> "
|
52
59
|
puts "logdir: #{option.logdir}"
|
@@ -58,8 +65,10 @@ module Qdumpfs
|
|
58
65
|
command = Command.new(option)
|
59
66
|
command.run
|
60
67
|
rescue => e
|
61
|
-
|
62
|
-
|
68
|
+
if option.debug
|
69
|
+
p e.message
|
70
|
+
p e.backtrace
|
71
|
+
end
|
63
72
|
puts opt.help
|
64
73
|
exit
|
65
74
|
end
|
@@ -82,8 +91,6 @@ module Qdumpfs
|
|
82
91
|
verify
|
83
92
|
elsif @opt.cmd == 'delete'
|
84
93
|
delete('delete')
|
85
|
-
# elsif @opt.cmd == 'test'
|
86
|
-
# test
|
87
94
|
else
|
88
95
|
raise RuntimeError, "unknown command: #{@opt.cmd}"
|
89
96
|
end
|
@@ -130,11 +137,17 @@ module Qdumpfs
|
|
130
137
|
end
|
131
138
|
|
132
139
|
def filecount(dir)
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
result =
|
140
|
+
result = '0'
|
141
|
+
if windows?
|
142
|
+
pscmd = 'Get-ChildItem -Recurse -File | Measure-Object | %{$_.Count}'
|
143
|
+
cmd = "powershell -Command \"#{pscmd}\""
|
144
|
+
result = nil
|
145
|
+
Dir.chdir(dir) do
|
146
|
+
result = `#{cmd}`
|
147
|
+
result.chomp!
|
148
|
+
end
|
149
|
+
else
|
150
|
+
result = `find #{dir} | wc -l`
|
138
151
|
result.chomp!
|
139
152
|
end
|
140
153
|
result.to_i
|
@@ -146,29 +159,6 @@ module Qdumpfs
|
|
146
159
|
return src_count, dst_count
|
147
160
|
end
|
148
161
|
|
149
|
-
def get_snapshots(target_dir)
|
150
|
-
# 指定したディレクトリに含まれるバックアップフォルダ(日付つき)を全て取得
|
151
|
-
dd = "[0-9][0-9]"
|
152
|
-
dddd = dd + dd
|
153
|
-
# FIXME: Y10K problem.
|
154
|
-
dirs = []
|
155
|
-
glob_path = File.join(target_dir, dddd, dd, dd)
|
156
|
-
Dir.glob(glob_path).sort.find {|dir|
|
157
|
-
day, month, year = File.split_all(dir).reverse.map {|x| x.to_i }
|
158
|
-
path = dir
|
159
|
-
if File.directory?(path) and Date.valid_date?(year, month, day) and
|
160
|
-
dirs << path
|
161
|
-
end
|
162
|
-
}
|
163
|
-
dirs
|
164
|
-
end
|
165
|
-
|
166
|
-
def get_snapshot_date(snapshot)
|
167
|
-
# バックアップディレクトリのパス(日付つき)から日付を取得して返す
|
168
|
-
day, month, year = File.split_all(snapshot).reverse.map {|x| x.to_i }
|
169
|
-
Time.new(year, month, day)
|
170
|
-
end
|
171
|
-
|
172
162
|
def update_snapshot(src, latest, today)
|
173
163
|
# バックアップの差分コピーを実行
|
174
164
|
# src: コピー元ディレクトリ ex) i:/from/home
|
@@ -189,8 +179,8 @@ module Qdumpfs
|
|
189
179
|
# ファイルのアップデート
|
190
180
|
update_file(s, l, t)
|
191
181
|
dirs[t] = File.stat(s) if File.ftype(s) == "directory"
|
192
|
-
rescue
|
193
|
-
|
182
|
+
rescue => e
|
183
|
+
log("#{src}: #{e.message}")
|
194
184
|
next
|
195
185
|
end
|
196
186
|
end
|
@@ -224,8 +214,8 @@ module Qdumpfs
|
|
224
214
|
end
|
225
215
|
chown_if_root(type, s, t)
|
226
216
|
dirs[t] = File.stat(s) if File.ftype(s) == "directory"
|
227
|
-
rescue
|
228
|
-
|
217
|
+
rescue => e
|
218
|
+
log("#{src}: #{e.message}")
|
229
219
|
next
|
230
220
|
end
|
231
221
|
end
|
@@ -237,7 +227,7 @@ module Qdumpfs
|
|
237
227
|
|
238
228
|
#コピー元のスナップショット
|
239
229
|
src_snapshots = BackupDir.scan_backup_dirs(src)
|
240
|
-
@opt.
|
230
|
+
@opt.detect_expire_dirs(src_snapshots)
|
241
231
|
|
242
232
|
# コピー先の最新スナップショット
|
243
233
|
dst_snapshots = BackupDir.scan_backup_dirs(dst)
|
@@ -306,6 +296,9 @@ module Qdumpfs
|
|
306
296
|
|
307
297
|
@written_bytes = 0
|
308
298
|
start_time = Time.now
|
299
|
+
if @opt.backup_at
|
300
|
+
start_time = to_time(@opt.backup_at)
|
301
|
+
end
|
309
302
|
src = @opt.src
|
310
303
|
dst = @opt.dst
|
311
304
|
|
@@ -451,11 +444,9 @@ module Qdumpfs
|
|
451
444
|
|
452
445
|
def delete(cmd)
|
453
446
|
@opt.validate_directories(1)
|
454
|
-
|
455
447
|
start_time = Time.now
|
456
448
|
limit_time = start_time + (@opt.limit_sec)
|
457
|
-
log("##### #{cmd} start #{fmt(start_time)} => limit_time=#{fmt(limit_time)} #####")
|
458
|
-
|
449
|
+
log("##### #{cmd} delete-from=#{@opt.delete_from} delete-to=#{@opt.delete_to} start #{fmt(start_time)} => limit_time=#{fmt(limit_time)} #####")
|
459
450
|
@opt.dirs.each do |target_dir|
|
460
451
|
|
461
452
|
target_start = Time.now
|
@@ -476,6 +467,29 @@ module Qdumpfs
|
|
476
467
|
log("##### #{cmd} end #####")
|
477
468
|
end
|
478
469
|
|
470
|
+
def rm_dir(path)
|
471
|
+
can_delete = true
|
472
|
+
if @opt.dry_run
|
473
|
+
can_delete = false
|
474
|
+
elsif !FileTest.directory?(path)
|
475
|
+
can_delete = false
|
476
|
+
end
|
477
|
+
msg = can_delete ? "...ok..." : "...ng..."
|
478
|
+
print "Deleting #{path} #{msg}"
|
479
|
+
|
480
|
+
return unless can_delete
|
481
|
+
|
482
|
+
#それ以外は日付バックアップディレクトリ全体を削除
|
483
|
+
if windows?
|
484
|
+
# Windowsの場合
|
485
|
+
win_backup_path = to_win_path(path)
|
486
|
+
system("rmdir /S /Q #{win_backup_path}")
|
487
|
+
else
|
488
|
+
# Linux/macOSの場合
|
489
|
+
system("rm -rf #{path}")
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
479
493
|
def delete_target_dir(cmd, target_dir)
|
480
494
|
target_dir = to_unix_path(target_dir)
|
481
495
|
puts "<<<<< Target dir: #{target_dir} >>>>>"
|
@@ -488,40 +502,20 @@ module Qdumpfs
|
|
488
502
|
else
|
489
503
|
raise RuntimeError, "unknown command: #{cmd}"
|
490
504
|
end
|
491
|
-
|
492
|
-
# p @opt.keep_year
|
493
|
-
# p @opt.keep_month
|
494
|
-
# p @opt.keep_day
|
495
|
-
|
505
|
+
|
496
506
|
snapshots.each do |snapshot|
|
497
507
|
next if snapshot.keep
|
498
508
|
t_start = Time.now
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
if windows?
|
507
|
-
# Windowsの場合
|
508
|
-
win_backup_path = to_win_path(snapshot.path)
|
509
|
-
|
510
|
-
# byenow = "byenow"
|
511
|
-
# if which(byenow)
|
512
|
-
# print " bynow"
|
513
|
-
# system("byenow -y --delete-ntapi --one-liner #{snapshot.path}")
|
514
|
-
# else
|
515
|
-
# print " pass1"
|
516
|
-
# system("del /F /S /Q #{win_backup_path} > nul")
|
517
|
-
# print " pass2"
|
518
|
-
# system("rmdir /S /Q #{win_backup_path}")
|
519
|
-
# end
|
520
|
-
system("rmdir /S /Q #{win_backup_path}")
|
521
|
-
else
|
522
|
-
# Linux/macOSの場合
|
523
|
-
system("rm -rf #{snapshot.path}")
|
509
|
+
|
510
|
+
if @opt.delete_dirs.size > 0
|
511
|
+
#削除するディレクトリが指定されている場合日付バックアップディレクトリの下そのディレクトリを削除
|
512
|
+
@opt.delete_dirs.each do |delete_dir|
|
513
|
+
delete_path = File.join(snapshot.path, delete_dir)
|
514
|
+
rm_dir(delete_path)
|
524
515
|
end
|
516
|
+
else
|
517
|
+
#それ以外はバックアップディレクトリ全体が対象
|
518
|
+
rm_dir(snapshot.path)
|
525
519
|
end
|
526
520
|
|
527
521
|
t_end = Time.now
|
@@ -545,60 +539,6 @@ module Qdumpfs
|
|
545
539
|
end
|
546
540
|
end
|
547
541
|
|
548
|
-
# def delete
|
549
|
-
# @opt.validate_directories(1)
|
550
|
-
|
551
|
-
# start_time = Time.now
|
552
|
-
# limit_time = start_time + (@opt.limit_sec)
|
553
|
-
# log("##### delete start #{fmt(start_time)} => limit_time=#{fmt(limit_time)} #####")
|
554
|
-
# @opt.dirs.each do |target_dir|
|
555
|
-
# target_start = Time.now
|
556
|
-
# delete_target_dir(target_dir)
|
557
|
-
# target_end = Time.now
|
558
|
-
|
559
|
-
# # 次回expireにかかる時間を最終expire時間の半分と予想
|
560
|
-
# next_expire = (target_end - target_start) / 2
|
561
|
-
|
562
|
-
# cur_time = Time.now
|
563
|
-
# in_imit = (cur_time + next_expire) < limit_time
|
564
|
-
|
565
|
-
# log("## cur_time=#{fmt(cur_time)} + next_expire=#{next_expire} < limit_time=#{fmt(limit_time)} in_limit=#{in_limit} ## ")
|
566
|
-
# unless in_limit
|
567
|
-
# break
|
568
|
-
# end
|
569
|
-
# end
|
570
|
-
# log("##### delete end #####")
|
571
|
-
# end
|
572
|
-
|
573
|
-
# def delete_target_dir(target_dir)
|
574
|
-
# target_dir = to_unix_path(target_dir)
|
575
|
-
# puts "<<<<< Target dir: #{target_dir} >>>>>"
|
576
|
-
|
577
|
-
# snapshots = BackupDir.scan_backup_dirs(target_dir)
|
578
|
-
# @opt.detect_delete_dirs(snapshots)
|
579
|
-
|
580
|
-
# snapshots.each do |snapshot|
|
581
|
-
# next if snapshot.keep
|
582
|
-
# t_start = Time.now
|
583
|
-
# print "Deleting #{snapshot.path} ..."
|
584
|
-
|
585
|
-
# unless @opt.dry_run
|
586
|
-
# if windows?
|
587
|
-
# # Windowsの場合
|
588
|
-
# win_backup_path = to_win_path(snapshot.path)
|
589
|
-
# system("rmdir /S /Q #{win_backup_path}")
|
590
|
-
# else
|
591
|
-
# # Linux/macOSの場合
|
592
|
-
# system("rm -rf #{snapshot.path}")
|
593
|
-
# end
|
594
|
-
# end
|
595
|
-
# end
|
596
|
-
|
597
|
-
# t_end = Time.now
|
598
|
-
# diff = (t_end - t_start).to_i
|
599
|
-
# diff_hours = diff / 3600
|
600
|
-
# puts " done[#{diff} seconds = #{diff_hours} hours]."
|
601
|
-
# end
|
602
542
|
|
603
543
|
end
|
604
544
|
|
data/lib/qdumpfs/option.rb
CHANGED
@@ -140,14 +140,18 @@ module Qdumpfs
|
|
140
140
|
@keep_week = $1.to_i if keep =~ /(\d+)W/
|
141
141
|
@keep_day = $1.to_i if keep =~ /(\d+)D/
|
142
142
|
@delete_from = @opts[:delete_from]
|
143
|
-
@delete_to = @opts[:delete_to]
|
143
|
+
@delete_to = @opts[:delete_to]
|
144
|
+
@delete_dirs = @opts[:delete_dirs] || []
|
145
|
+
@backup_at = @opts[:backup_at]
|
144
146
|
@today = Date.today
|
147
|
+
@debug = @opts[:d]
|
145
148
|
end
|
146
149
|
attr_reader :dirs, :src, :dst, :cmd
|
147
150
|
attr_reader :keep_year, :keep_month, :keep_week, :keep_day
|
148
151
|
attr_reader :logdir, :logpath, :verifypath
|
149
152
|
attr_reader :logger, :matcher, :reporter, :interval_proc
|
150
|
-
attr_reader :delete_from, :delete_to
|
153
|
+
attr_reader :delete_from, :delete_to, :delete_dirs, :backup_at
|
154
|
+
attr_reader :debug
|
151
155
|
|
152
156
|
def report(type, filename)
|
153
157
|
if @opts[:v]
|
@@ -217,14 +221,21 @@ module Qdumpfs
|
|
217
221
|
end
|
218
222
|
|
219
223
|
def detect_delete_dirs(backup_dirs, delete_from, delete_to)
|
224
|
+
|
220
225
|
backup_dirs.each do |backup_dir|
|
221
226
|
backup_dir.keep = true
|
222
|
-
if delete_from &&
|
223
|
-
backup_dir.
|
224
|
-
|
225
|
-
|
226
|
-
elsif
|
227
|
-
backup_dir.
|
227
|
+
if delete_from && delete_to
|
228
|
+
if backup_dir.date >= delete_from && backup_dir.date <= delete_to
|
229
|
+
backup_dir.keep = false
|
230
|
+
end
|
231
|
+
elsif delete_from
|
232
|
+
if backup_dir.date >= delete_from
|
233
|
+
backup_dir.keep = false
|
234
|
+
end
|
235
|
+
elsif delete_to
|
236
|
+
if backup_dir.date <= delete_to
|
237
|
+
backup_dir.keep = false
|
238
|
+
end
|
228
239
|
end
|
229
240
|
end
|
230
241
|
end
|
data/lib/qdumpfs/util.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# coding: utf-8
|
1
2
|
def wprintf(format, *args)
|
2
3
|
STDERR.printf("pdumpfs: " + format + "\n", *args)
|
3
4
|
end
|
@@ -72,14 +73,14 @@ module QdumpfsFind
|
|
72
73
|
yield file.dup.taint
|
73
74
|
begin
|
74
75
|
s = File.lstat(file)
|
75
|
-
rescue
|
76
|
+
rescue => e
|
76
77
|
logger.print("File.lstat path=#{file} error=#{e.message}")
|
77
78
|
next
|
78
79
|
end
|
79
80
|
if s.directory? then
|
80
81
|
begin
|
81
82
|
fs = Dir.entries(file, :encoding=>'UTF-8')
|
82
|
-
rescue
|
83
|
+
rescue => e
|
83
84
|
logger.print("Dir.entries path=#{file} error=#{e.message}")
|
84
85
|
next
|
85
86
|
end
|
@@ -106,23 +107,22 @@ module QdumpfsUtils
|
|
106
107
|
|
107
108
|
# We don't use File.copy for calling @interval_proc.
|
108
109
|
def copy_file(src, dest)
|
109
|
-
|
110
|
-
File.open(
|
111
|
-
|
112
|
-
|
110
|
+
begin
|
111
|
+
File.open(src, 'rb') {|r|
|
112
|
+
File.open(dest, 'wb') {|w|
|
113
|
+
block_size = (r.stat.blksize or 8192)
|
113
114
|
i = 0
|
114
115
|
while true
|
115
116
|
block = r.sysread(block_size)
|
116
117
|
w.syswrite(block)
|
117
118
|
i += 1
|
118
119
|
@written_bytes += block.size
|
119
|
-
# @interval_proc.call if i % 10 == 0
|
120
120
|
end
|
121
|
-
|
122
|
-
# puts e.message, e.backtrace
|
123
|
-
end
|
121
|
+
}
|
124
122
|
}
|
125
|
-
|
123
|
+
rescue EOFError => e
|
124
|
+
# puts e.message, e.backtrace
|
125
|
+
end
|
126
126
|
unless FileTest.file?(dest)
|
127
127
|
raise "copy_file fails #{dest}"
|
128
128
|
end
|
@@ -278,6 +278,10 @@ module QdumpfsUtils
|
|
278
278
|
|
279
279
|
def to_unix_path(path)
|
280
280
|
path.gsub(/\\/, '/')
|
281
|
-
end
|
281
|
+
end
|
282
|
+
|
283
|
+
def to_time(date)
|
284
|
+
Time.local(date.year, date.month, date.day)
|
285
|
+
end
|
282
286
|
end
|
283
287
|
|
data/lib/qdumpfs/version.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
-
module Qdumpfs
|
2
|
-
VERSION = "0.
|
3
|
-
end
|
1
|
+
module Qdumpfs
|
2
|
+
VERSION = "1.0.1"
|
3
|
+
end
|
4
|
+
|
data/run_list.sh
ADDED
data/run_qdumpfs.sh
CHANGED
data/sample.sh
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qdumpfs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- src
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-04-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -57,6 +57,7 @@ email:
|
|
57
57
|
- src@srcw.net
|
58
58
|
executables:
|
59
59
|
- qdumpfs
|
60
|
+
- sample
|
60
61
|
extensions: []
|
61
62
|
extra_rdoc_files: []
|
62
63
|
files:
|
@@ -73,7 +74,10 @@ files:
|
|
73
74
|
- bin/setup
|
74
75
|
- build.cmd
|
75
76
|
- build.sh
|
77
|
+
- data/from/0.txt
|
78
|
+
- data/from/a/1.txt
|
76
79
|
- exe/qdumpfs
|
80
|
+
- exe/sample
|
77
81
|
- lib/qdumpfs.rb
|
78
82
|
- lib/qdumpfs/option.rb
|
79
83
|
- lib/qdumpfs/util.rb
|
@@ -82,9 +86,11 @@ files:
|
|
82
86
|
- qdumpfs.gemspec
|
83
87
|
- run2_qdumpfs.cmd
|
84
88
|
- run_list.cmd
|
89
|
+
- run_list.sh
|
85
90
|
- run_qdumpfs.cmd
|
86
91
|
- run_qdumpfs.sh
|
87
92
|
- run_sync.cmd
|
93
|
+
- sample.sh
|
88
94
|
- test_pdumpfs/data/bar
|
89
95
|
- test_pdumpfs/data/baz/quux
|
90
96
|
- test_pdumpfs/data/file
|