qdumpfs 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +23 -0
- data/LICENSE.txt +339 -0
- data/README.md +31 -0
- data/Rakefile +10 -0
- data/TODO.txt +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/build.cmd +14 -0
- data/build.sh +19 -0
- data/exe/qdumpfs +6 -0
- data/lib/qdumpfs.rb +540 -0
- data/lib/qdumpfs/option.rb +302 -0
- data/lib/qdumpfs/util.rb +283 -0
- data/lib/qdumpfs/version.rb +3 -0
- data/lib/qdumpfs/win32.rb +146 -0
- data/qdumpfs.gemspec +43 -0
- data/run2_qdumpfs.cmd +6 -0
- data/run_list.cmd +7 -0
- data/run_qdumpfs.cmd +5 -0
- data/run_qdumpfs.sh +4 -0
- data/run_sync.cmd +6 -0
- data/test_pdumpfs/data/bar +1 -0
- data/test_pdumpfs/data/baz/quux +1 -0
- data/test_pdumpfs/data/file +1 -0
- data/test_pdumpfs/data/foo +1 -0
- data/test_pdumpfs/data/secret/secret +1 -0
- data/test_pdumpfs/pdumpfs-test +86 -0
- metadata +120 -0
@@ -0,0 +1,146 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
def windows?
|
4
|
+
/mswin32|cygwin|mingw|bccwin/.match(RUBY_PLATFORM)
|
5
|
+
end
|
6
|
+
|
7
|
+
if windows?
|
8
|
+
# http://www.virtuouscode.com/2011/08/25/temporarily-disabling-warnings-in-ruby/
|
9
|
+
|
10
|
+
# https://stackoverflow.com/questions/39051793/can-i-hide-the-warning-message-dl-is-deprecated-please-use-fiddle-in-ruby
|
11
|
+
original_verbose = $VERBOSE
|
12
|
+
$VERBOSE = nil
|
13
|
+
|
14
|
+
require 'Win32API'
|
15
|
+
require "win32ole"
|
16
|
+
|
17
|
+
$VERBOSE = original_verbose
|
18
|
+
|
19
|
+
if RUBY_VERSION < "1.8.0"
|
20
|
+
CreateHardLinkA = Win32API.new("kernel32", "CreateHardLinkA", "ppl", 'i')
|
21
|
+
def File.link(l, t)
|
22
|
+
result = CreateHardLinkA.call(t, l, 0)
|
23
|
+
|
24
|
+
raise Errno::EACCES if result == 0
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def expand_special_folders(dir)
|
29
|
+
specials = %w[(?:AllUsers)?(?:Desktop|Programs|Start(?:Menu|up)) Favorites
|
30
|
+
Fonts MyDocuments NetHood PrintHood Recent SendTo Templates]
|
31
|
+
|
32
|
+
pattern = Regexp.compile(sprintf('^@(%s)', specials.join('|')))
|
33
|
+
|
34
|
+
dir.sub(pattern) do |match|
|
35
|
+
WIN32OLE.new("WScript.Shell").SpecialFolders(match)
|
36
|
+
end.tr('\\', File::SEPARATOR)
|
37
|
+
end
|
38
|
+
|
39
|
+
GetVolumeInformation = Win32API.new("kernel32", "GetVolumeInformation", "PPLPPPPL", "I")
|
40
|
+
def get_filesystem_type(path)
|
41
|
+
return nil unless(FileTest.exist?(path))
|
42
|
+
|
43
|
+
drive = File.expand_path(path)[0..2]
|
44
|
+
buff = "\0" * 1024
|
45
|
+
GetVolumeInformation.call(drive, nil, 0, nil, nil, nil, buff, 1024)
|
46
|
+
|
47
|
+
buff.sub(/\000+/, '')
|
48
|
+
end
|
49
|
+
|
50
|
+
def ntfs?(dir)
|
51
|
+
get_filesystem_type(dir) == "NTFS"
|
52
|
+
end
|
53
|
+
|
54
|
+
GetLocaltime = Win32API.new("kernel32", "GetLocalTime", "P", 'V')
|
55
|
+
SystemTimeToFileTime = Win32API.new("kernel32", "SystemTimeToFileTime", "PP", 'I')
|
56
|
+
def get_file_time(time)
|
57
|
+
pSYSTEMTIME = ' ' * 2 * 8 # 2byte x 8
|
58
|
+
pFILETIME = ' ' * 2 * 8 # 2byte x 8
|
59
|
+
|
60
|
+
GetLocaltime.call(pSYSTEMTIME)
|
61
|
+
t1 = pSYSTEMTIME.unpack("S8")
|
62
|
+
t1[0..1] = time.year, time.month
|
63
|
+
t1[3..6] = time.day, time.hour, time.min, time.sec
|
64
|
+
|
65
|
+
SystemTimeToFileTime.call(t1.pack("S8"), pFILETIME)
|
66
|
+
|
67
|
+
pFILETIME
|
68
|
+
end
|
69
|
+
|
70
|
+
GENERIC_WRITE = 0x40000000
|
71
|
+
OPEN_EXISTING = 3
|
72
|
+
FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
|
73
|
+
|
74
|
+
class << File
|
75
|
+
alias_method(:utime_orig, :utime)
|
76
|
+
end
|
77
|
+
|
78
|
+
CreateFile = Win32API.new("kernel32", "CreateFileA","PLLLLLL", "L")
|
79
|
+
SetFileTime = Win32API.new("kernel32", "SetFileTime", "LPPP", "I")
|
80
|
+
CloseHandle = Win32API.new("kernel32", "CloseHandle", "L", "I")
|
81
|
+
|
82
|
+
def File.utime(a, m, dir)
|
83
|
+
File.utime_orig(a, m, dir) unless(File.directory?(dir))
|
84
|
+
|
85
|
+
atime = get_file_time(a.dup.utc)
|
86
|
+
mtime = get_file_time(m.dup.utc)
|
87
|
+
|
88
|
+
hDir = CreateFile.Call(dir.dup, GENERIC_WRITE, 0, 0, OPEN_EXISTING,
|
89
|
+
FILE_FLAG_BACKUP_SEMANTICS, 0)
|
90
|
+
SetFileTime.call(hDir, 0, atime, mtime)
|
91
|
+
CloseHandle.Call(hDir)
|
92
|
+
|
93
|
+
return 0
|
94
|
+
end
|
95
|
+
|
96
|
+
LOCALE_USER_DEFAULT = 0x400
|
97
|
+
LOCALE_SABBREVLANGNAME = 3
|
98
|
+
LOCALE_USE_CP_ACP = 0x40000000
|
99
|
+
GetLocaleInfo = Win32API.new("kernel32", "GetLocaleInfo", "IIPI", "I")
|
100
|
+
|
101
|
+
def get_locale_name
|
102
|
+
locale_name = " " * 32
|
103
|
+
status = GetLocaleInfo.call(LOCALE_USER_DEFAULT,
|
104
|
+
LOCALE_SABBREVLANGNAME | LOCALE_USE_CP_ACP,
|
105
|
+
locale_name, 32)
|
106
|
+
if status == 0
|
107
|
+
return nil
|
108
|
+
else
|
109
|
+
return locale_name.split("\x00").first
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
SW_HIDE = 0
|
114
|
+
SW_SHOWNORMAL = 1
|
115
|
+
|
116
|
+
ShellExecute = Win32API.new("shell32", "ShellExecute", "LPPPPL", 'L')
|
117
|
+
LoadIcon = Win32API.new("user32", "LoadIcon", "II", "I")
|
118
|
+
GetModuleFileName = Win32API.new("kernel32", "GetModuleFileName","IPI","I")
|
119
|
+
|
120
|
+
def get_exe_file_name
|
121
|
+
path = "\0" * 1024
|
122
|
+
length = GetModuleFileName.call(0 ,path, path.length)
|
123
|
+
return path[0, length].tr('\\', File::SEPARATOR)
|
124
|
+
end
|
125
|
+
|
126
|
+
def get_program_file_name
|
127
|
+
exe_file_name = get_exe_file_name
|
128
|
+
if File.basename(exe_file_name) == "ruby.exe"
|
129
|
+
return File.expand_path($0).gsub('\\', File::SEPARATOR)
|
130
|
+
else
|
131
|
+
return exe_file_name
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def get_program_directory
|
136
|
+
program_file_name = get_program_file_name
|
137
|
+
return File.dirname(program_file_name)
|
138
|
+
end
|
139
|
+
|
140
|
+
def init
|
141
|
+
locale_name = get_locale_name
|
142
|
+
# $KCODE = "SJIS" if locale_name == "JPN"
|
143
|
+
end
|
144
|
+
|
145
|
+
init
|
146
|
+
end
|
data/qdumpfs.gemspec
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "qdumpfs/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "qdumpfs"
|
8
|
+
spec.version = Qdumpfs::VERSION
|
9
|
+
spec.authors = ["src"]
|
10
|
+
spec.email = ["src@srcw.net"]
|
11
|
+
|
12
|
+
spec.summary = %q{qdumpfs}
|
13
|
+
spec.description = %q{qdumpfs}
|
14
|
+
spec.homepage = "https://github.com/src256/qdumpfs"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
# spec.metadata["allowed_push_host"] = spec.homepage
|
21
|
+
|
22
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
23
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
24
|
+
spec.metadata["changelog_uri"] = spec.homepage
|
25
|
+
else
|
26
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
27
|
+
"public gem pushes."
|
28
|
+
end
|
29
|
+
|
30
|
+
# Specify which files should be added to the gem when it is released.
|
31
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
32
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
33
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
34
|
+
end
|
35
|
+
spec.bindir = "exe"
|
36
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
37
|
+
spec.require_paths = ["lib"]
|
38
|
+
|
39
|
+
spec.add_development_dependency "bundler", "~> 1.17"
|
40
|
+
# spec.add_development_dependency "rake", "~> 10.0"
|
41
|
+
spec.add_development_dependency "rake", ">= 12.3.3"
|
42
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
43
|
+
end
|
data/run2_qdumpfs.cmd
ADDED
data/run_list.cmd
ADDED
data/run_qdumpfs.cmd
ADDED
data/run_qdumpfs.sh
ADDED
data/run_sync.cmd
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
bar
|
@@ -0,0 +1 @@
|
|
1
|
+
quux
|
@@ -0,0 +1 @@
|
|
1
|
+
realfile
|
@@ -0,0 +1 @@
|
|
1
|
+
foo
|
@@ -0,0 +1 @@
|
|
1
|
+
foo
|
@@ -0,0 +1,86 @@
|
|
1
|
+
#! /bin/sh
|
2
|
+
|
3
|
+
function mode_type {
|
4
|
+
ruby -e "printf %Q(%o:%s\n), File.stat(%q($1)).mode, File.ftype(%q($1))"
|
5
|
+
}
|
6
|
+
|
7
|
+
rm -rf src dest
|
8
|
+
|
9
|
+
# コピー先ディレクトリdestを作成
|
10
|
+
# dataをsrcとしてコピーしその中のfooをfoobarという名前でシンボリックリンク
|
11
|
+
mkdir dest
|
12
|
+
cp -rp data src
|
13
|
+
cd src
|
14
|
+
ln -s foo foobar
|
15
|
+
cd ..
|
16
|
+
|
17
|
+
today=`date +%Y/%m/%d`
|
18
|
+
yesterday=`date -v -1d +%Y/%m/%d`
|
19
|
+
|
20
|
+
# srcディレクトリの内容を正しくコピーできているかどうか
|
21
|
+
../run_qdumpfs.sh src dest > tmp.log || exit 1
|
22
|
+
../run_qdumpfs.sh src dest
|
23
|
+
diff -r src dest/$today/src || exit 1
|
24
|
+
|
25
|
+
# 更新のテスト
|
26
|
+
mv dest/$today dest/$yesterday
|
27
|
+
# 新しいファイルとフォルダの作成
|
28
|
+
echo update > src/foo
|
29
|
+
mkdir src/newdir
|
30
|
+
echo newfile > src/newdir/newfile
|
31
|
+
echo newfile2 > src/newfile2
|
32
|
+
# ファイルの削除
|
33
|
+
rm -f src/bar
|
34
|
+
# ファイルをシンボリックリンクへ変更
|
35
|
+
rm src/file
|
36
|
+
cd src
|
37
|
+
ln -s foo file
|
38
|
+
cd ..
|
39
|
+
# 更新実行
|
40
|
+
../run_qdumpfs.sh src dest > tmp.log || exit 1
|
41
|
+
# 正しくコピーできているか
|
42
|
+
diff -r src dest/$today/src || exit 1
|
43
|
+
|
44
|
+
|
45
|
+
unchanged=("baz/quux" "secret/secret")
|
46
|
+
for i in "${unchanged[@]}"
|
47
|
+
do
|
48
|
+
# i1=`ls -i dest/$yesterday/src/$i`
|
49
|
+
# i2=`ls -i dest/$today/src/$i`
|
50
|
+
i1=`stat -f %c dest/$yesterday/src/$i`
|
51
|
+
i2=`stat -f %c dest/$today/src/$i`
|
52
|
+
test "$i1" = "$i2" || exit 1
|
53
|
+
done
|
54
|
+
|
55
|
+
|
56
|
+
find src |sort | while read srcfile; do
|
57
|
+
destfile="dest/$today/$srcfile"
|
58
|
+
if test "`mode_type $srcfile`" != "`mode_type $destfile`"; then
|
59
|
+
echo "error: modes of $srcfile and $destfile differ"
|
60
|
+
exit 1
|
61
|
+
fi
|
62
|
+
done || exit 1
|
63
|
+
|
64
|
+
|
65
|
+
# dest2にファイルがコピーされない事を確認
|
66
|
+
rm -rf dest2
|
67
|
+
mkdir dest2
|
68
|
+
|
69
|
+
../run_qdumpfs.sh --exclude-by-size=0 src dest > tmp.log || exit 1
|
70
|
+
test `find dest2 -type f | wc -l` = 0 || exit 1
|
71
|
+
|
72
|
+
|
73
|
+
rm -rf dest3
|
74
|
+
mkdir dest3
|
75
|
+
../run_qdumpfs.sh --exclude=foo --exclude bar src dest3 > tmp.log || exit 1
|
76
|
+
test -z "`find dest3 -type f | egrep 'foo|bar'`" || exit 1
|
77
|
+
|
78
|
+
rm -rf dest4
|
79
|
+
mkdir dest4
|
80
|
+
../run_qdumpfs.sh --exclude-by-glob='new*' src dest4 > tmp.log || exit 1
|
81
|
+
test -z "`find dest4 -type f | egrep new`" || exit 1
|
82
|
+
|
83
|
+
rm -rf src dest dest?
|
84
|
+
|
85
|
+
echo ok.
|
86
|
+
exit 0
|
metadata
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: qdumpfs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- src
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-05-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.17'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.17'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 12.3.3
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 12.3.3
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
55
|
+
description: qdumpfs
|
56
|
+
email:
|
57
|
+
- src@srcw.net
|
58
|
+
executables:
|
59
|
+
- qdumpfs
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".gitignore"
|
64
|
+
- ".travis.yml"
|
65
|
+
- CODE_OF_CONDUCT.md
|
66
|
+
- Gemfile
|
67
|
+
- Gemfile.lock
|
68
|
+
- LICENSE.txt
|
69
|
+
- README.md
|
70
|
+
- Rakefile
|
71
|
+
- TODO.txt
|
72
|
+
- bin/console
|
73
|
+
- bin/setup
|
74
|
+
- build.cmd
|
75
|
+
- build.sh
|
76
|
+
- exe/qdumpfs
|
77
|
+
- lib/qdumpfs.rb
|
78
|
+
- lib/qdumpfs/option.rb
|
79
|
+
- lib/qdumpfs/util.rb
|
80
|
+
- lib/qdumpfs/version.rb
|
81
|
+
- lib/qdumpfs/win32.rb
|
82
|
+
- qdumpfs.gemspec
|
83
|
+
- run2_qdumpfs.cmd
|
84
|
+
- run_list.cmd
|
85
|
+
- run_qdumpfs.cmd
|
86
|
+
- run_qdumpfs.sh
|
87
|
+
- run_sync.cmd
|
88
|
+
- test_pdumpfs/data/bar
|
89
|
+
- test_pdumpfs/data/baz/quux
|
90
|
+
- test_pdumpfs/data/file
|
91
|
+
- test_pdumpfs/data/foo
|
92
|
+
- test_pdumpfs/data/secret/secret
|
93
|
+
- test_pdumpfs/pdumpfs-test
|
94
|
+
homepage: https://github.com/src256/qdumpfs
|
95
|
+
licenses:
|
96
|
+
- MIT
|
97
|
+
metadata:
|
98
|
+
homepage_uri: https://github.com/src256/qdumpfs
|
99
|
+
source_code_uri: https://github.com/src256/qdumpfs
|
100
|
+
changelog_uri: https://github.com/src256/qdumpfs
|
101
|
+
post_install_message:
|
102
|
+
rdoc_options: []
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
requirements: []
|
116
|
+
rubygems_version: 3.0.3
|
117
|
+
signing_key:
|
118
|
+
specification_version: 4
|
119
|
+
summary: qdumpfs
|
120
|
+
test_files: []
|