recls-ruby 2.13.0.1 → 2.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/recls/version.rb +2 -2
- data/lib/recls/ximpl/windows.rb +170 -54
- data/test/unit/tc_recls_entry.rb +18 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0da3b80a1f5ba1babc0fdfbd56abf30433e53d39f2996fe2661d0142ad4b386d
|
4
|
+
data.tar.gz: 47fca376aac5eb7559fe2b7e014b8a79d23bc828fcbd999b75ce133a52a4e255
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1c79afd72e02b47c8c9ce9291c08d1c825e96e5e66a826a36a004c08774b82e77aa5610edc0c986ebfa28b10c95f5baea75ed9bdfba12ac35a36a377fd7b747
|
7
|
+
data.tar.gz: dcdfee4db3cddd95879d7faf833def2daea1cdc8d91809981dfbbb3703dacc37ce77b4c1671b33dafb60d7ec446ffee6afe3a389b5de97d4063b157c5ace4b63
|
data/lib/recls/version.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# Purpose: Version for recls library
|
5
5
|
#
|
6
6
|
# Created: 14th February 2014
|
7
|
-
# Updated:
|
7
|
+
# Updated: 2nd April 2024
|
8
8
|
#
|
9
9
|
# Author: Matthew Wilson
|
10
10
|
#
|
@@ -43,7 +43,7 @@
|
|
43
43
|
module Recls
|
44
44
|
|
45
45
|
# Current version of the recls.Ruby library
|
46
|
-
VERSION = '2.13.
|
46
|
+
VERSION = '2.13.1'
|
47
47
|
|
48
48
|
private
|
49
49
|
# @!visibility private
|
data/lib/recls/ximpl/windows.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# Purpose: Windows-specific constructs for the recls library.
|
5
5
|
#
|
6
6
|
# Created: 19th February 2014
|
7
|
-
# Updated:
|
7
|
+
# Updated: 2nd June 2024
|
8
8
|
#
|
9
9
|
# Author: Matthew Wilson
|
10
10
|
#
|
@@ -37,7 +37,14 @@
|
|
37
37
|
# ######################################################################## #
|
38
38
|
|
39
39
|
|
40
|
-
|
40
|
+
if RUBY_VERSION >= '2'
|
41
|
+
|
42
|
+
require 'fiddle'
|
43
|
+
require 'fiddle/import'
|
44
|
+
else
|
45
|
+
|
46
|
+
require 'Win32API'
|
47
|
+
end
|
41
48
|
|
42
49
|
|
43
50
|
=begin
|
@@ -49,46 +56,136 @@ module Recls
|
|
49
56
|
module Ximpl # :nodoc: all
|
50
57
|
|
51
58
|
# @!visibility private
|
52
|
-
|
59
|
+
module Kernel32
|
60
|
+
|
61
|
+
MAX_PATH = 260
|
62
|
+
NULL = 0x00000000
|
63
|
+
OPEN_EXISTING = 0x00000003
|
64
|
+
end # module Kernel32
|
65
|
+
|
66
|
+
if RUBY_VERSION >= '2'
|
67
|
+
|
68
|
+
module Kernel32
|
69
|
+
extend Fiddle::Importer
|
70
|
+
|
71
|
+
dlload 'kernel32.dll'
|
72
|
+
|
73
|
+
typealias 'BOOL', 'int'
|
74
|
+
typealias 'DWORD', 'unsigned long'
|
75
|
+
typealias 'HANDLE', 'void*'
|
76
|
+
|
77
|
+
BY_HANDLE_FILE_INFORMATION = struct [
|
78
|
+
'DWORD dwFileAttributes',
|
79
|
+
'DWORD ftCreationTime_0',
|
80
|
+
'DWORD ftCreationTime_1',
|
81
|
+
'DWORD ftLastAccessTime_0',
|
82
|
+
'DWORD ftLastAccessTime_1',
|
83
|
+
'DWORD ftLastWriteTime_0',
|
84
|
+
'DWORD ftLastWriteTime_1',
|
85
|
+
'DWORD dwVolumeSerialNumber',
|
86
|
+
'DWORD nFileSizeHigh',
|
87
|
+
'DWORD nFileSizeLow',
|
88
|
+
'DWORD nNumberOfLinks',
|
89
|
+
'DWORD nFileIndexHigh',
|
90
|
+
'DWORD nFileIndexLow',
|
91
|
+
]
|
92
|
+
|
93
|
+
extern 'BOOL CloseHandle(HANDLE)'
|
94
|
+
extern 'HANDLE CreateFileA(const char*, DWORD, DWORD, void*, DWORD, DWORD, HANDLE)'
|
95
|
+
extern 'DWORD GetFileAttributesA(const char*)'
|
96
|
+
extern 'BOOL GetFileInformationByHandle(HANDLE, BY_HANDLE_FILE_INFORMATION*)'
|
97
|
+
extern 'DWORD GetShortPathNameA(const char*, char*, DWORD)'
|
98
|
+
|
99
|
+
INVALID_HANDLE_VALUE = Fiddle::Pointer[-1]
|
100
|
+
end # module Kernel32
|
101
|
+
|
102
|
+
module Kernel32
|
103
|
+
def self.get_file_attributes(path)
|
104
|
+
|
105
|
+
attributes = GetFileAttributesA(path)
|
106
|
+
|
107
|
+
(0xFFFFFFFF == attributes) ? 0 : attributes
|
108
|
+
end
|
53
109
|
|
54
|
-
|
55
|
-
GetFileAttributes = Win32API.new('kernel32', 'GetFileAttributes', [ 'P' ], 'I')
|
56
|
-
GetFileInformationByHandle = Win32API.new('kernel32', 'GetFileInformationByHandle', [ 'L', 'P' ], 'I')
|
57
|
-
GetShortPathName = Win32API.new('kernel32', 'GetShortPathName', [ 'P', 'P', 'L' ], 'L')
|
58
|
-
CreateFile = Win32API.new('kernel32', 'CreateFile', [ 'P', 'L', 'L', 'L', 'L', 'L', 'L' ], 'L')
|
59
|
-
CloseHandle = Win32API.new('kernel32', 'CloseHandle', [ 'L' ], 'L')
|
60
|
-
FILE_ATTRIBUTE_READONLY = 0x00000001
|
61
|
-
FILE_ATTRIBUTE_HIDDEN = 0x00000002
|
62
|
-
FILE_ATTRIBUTE_SYSTEM = 0x00000004
|
63
|
-
FILE_ATTRIBUTE_DIRECTORY = 0x00000010
|
64
|
-
FILE_ATTRIBUTE_ARCHIVE = 0x00000020
|
65
|
-
FILE_ATTRIBUTE_DEVICE = 0x00000040
|
66
|
-
FILE_ATTRIBUTE_NORMAL = 0x00000080
|
67
|
-
FILE_ATTRIBUTE_TEMPORARY = 0x00000100
|
68
|
-
FILE_ATTRIBUTE_COMPRESSED = 0x00000800
|
69
|
-
FILE_ATTRIBUTE_ENCRYPTED = 0x00004000
|
110
|
+
def self.get_short_path_name(path)
|
70
111
|
|
71
|
-
|
72
|
-
FILE_FLAG_OVERLAPPED = 0x40000000
|
73
|
-
NULL = 0x00000000
|
74
|
-
INVALID_HANDLE_VALUE = 0xFFFFFFFF
|
112
|
+
buff = ' ' * MAX_PATH
|
75
113
|
|
76
|
-
|
114
|
+
buf = Fiddle::Pointer[buff]
|
77
115
|
|
78
|
-
|
116
|
+
n = GetShortPathNameA(path, buf, buf.size)
|
79
117
|
|
80
|
-
|
81
|
-
|
118
|
+
(0 == n) ? nil : buff[0...n]
|
119
|
+
end
|
82
120
|
|
83
|
-
|
84
|
-
|
121
|
+
def self.get_stat_shared(path)
|
122
|
+
|
123
|
+
volume_id = 0
|
124
|
+
file_index = 0
|
125
|
+
num_links = 0
|
85
126
|
|
86
|
-
|
87
|
-
|
88
|
-
|
127
|
+
hFile = CreateFileA(path, 0, 0, NULL, OPEN_EXISTING, 0, NULL)
|
128
|
+
|
129
|
+
if INVALID_HANDLE_VALUE != hFile
|
130
|
+
|
131
|
+
begin
|
132
|
+
bhfi = BY_HANDLE_FILE_INFORMATION.malloc
|
133
|
+
|
134
|
+
if GetFileInformationByHandle(hFile, bhfi)
|
135
|
+
|
136
|
+
volume_id = bhfi.dwVolumeSerialNumber
|
137
|
+
file_index = (bhfi.nFileIndexHigh << 32) | bhfi.nFileIndexLow
|
138
|
+
num_links = bhfi.nNumberOfLinks
|
139
|
+
end
|
140
|
+
ensure
|
141
|
+
|
142
|
+
CloseHandle(hFile)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
[ volume_id, file_index, num_links ]
|
147
|
+
end
|
148
|
+
end # module Kernel32
|
149
|
+
else
|
150
|
+
|
151
|
+
module Kernel32
|
152
|
+
|
153
|
+
CloseHandle = Win32API.new('kernel32', 'CloseHandle', [ 'L' ], 'L')
|
154
|
+
CreateFile = Win32API.new('kernel32', 'CreateFile', [ 'P', 'L', 'L', 'L', 'L', 'L', 'L' ], 'L')
|
155
|
+
GetFileAttributes = Win32API.new('kernel32', 'GetFileAttributes', [ 'P' ], 'I')
|
156
|
+
GetFileInformationByHandle = Win32API.new('kernel32', 'GetFileInformationByHandle', [ 'L', 'P' ], 'I')
|
157
|
+
GetShortPathName = Win32API.new('kernel32', 'GetShortPathName', [ 'P', 'P', 'L' ], 'L')
|
158
|
+
|
159
|
+
INVALID_HANDLE_VALUE = -1
|
160
|
+
|
161
|
+
BHFI_pack_string = 'LQQQLLLLLL'
|
162
|
+
end # module Kernel32
|
163
|
+
|
164
|
+
module Kernel32
|
165
|
+
def self.get_file_attributes(path)
|
166
|
+
|
167
|
+
attributes = GetFileAttributes.call(path)
|
168
|
+
|
169
|
+
(0xFFFFFFFF == attributes) ? 0 : attributes
|
170
|
+
end
|
171
|
+
|
172
|
+
def self.get_short_path_name(path)
|
173
|
+
|
174
|
+
buff = ' ' * MAX_PATH
|
175
|
+
|
176
|
+
n = GetShortPathName.call(path, buff, buff.length)
|
177
|
+
|
178
|
+
(0 == n) ? nil : buff[0...n]
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.get_stat_shared(path)
|
182
|
+
|
183
|
+
volume_id = 0
|
184
|
+
file_index = 0
|
185
|
+
num_links = 0
|
186
|
+
|
187
|
+
hFile = CreateFile.call(path, 0, 0, NULL, OPEN_EXISTING, 0, NULL)
|
89
188
|
|
90
|
-
# for some reason not forcing this new string causes 'can't modify frozen string (TypeError)' (in Ruby 1.8.x)
|
91
|
-
hFile = CreateFile.call("#{path}", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
|
92
189
|
if INVALID_HANDLE_VALUE != hFile
|
93
190
|
|
94
191
|
begin
|
@@ -99,15 +196,43 @@ module Recls
|
|
99
196
|
|
100
197
|
bhfi = bhfi.unpack(BHFI_pack_string)
|
101
198
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
else
|
199
|
+
volume_id = bhfi[4]
|
200
|
+
file_index = (bhfi[8] << 32) | bhfi[9]
|
201
|
+
num_links = bhfi[7]
|
106
202
|
end
|
107
203
|
ensure
|
204
|
+
|
108
205
|
CloseHandle.call(hFile)
|
109
206
|
end
|
110
207
|
end
|
208
|
+
|
209
|
+
[ volume_id, file_index, num_links ]
|
210
|
+
end
|
211
|
+
end # module Kernel32
|
212
|
+
end
|
213
|
+
|
214
|
+
# @!visibility private
|
215
|
+
class FileStat < File::Stat # :nodoc:
|
216
|
+
|
217
|
+
private
|
218
|
+
FILE_ATTRIBUTE_READONLY = 0x00000001
|
219
|
+
FILE_ATTRIBUTE_HIDDEN = 0x00000002
|
220
|
+
FILE_ATTRIBUTE_SYSTEM = 0x00000004
|
221
|
+
FILE_ATTRIBUTE_DIRECTORY = 0x00000010
|
222
|
+
FILE_ATTRIBUTE_ARCHIVE = 0x00000020
|
223
|
+
FILE_ATTRIBUTE_DEVICE = 0x00000040
|
224
|
+
FILE_ATTRIBUTE_NORMAL = 0x00000080
|
225
|
+
FILE_ATTRIBUTE_TEMPORARY = 0x00000100
|
226
|
+
FILE_ATTRIBUTE_COMPRESSED = 0x00000800
|
227
|
+
FILE_ATTRIBUTE_ENCRYPTED = 0x00004000
|
228
|
+
|
229
|
+
# @!visibility private
|
230
|
+
class ByHandleInformation # :nodoc:
|
231
|
+
|
232
|
+
# @!visibility private
|
233
|
+
def initialize(path) # :nodoc:
|
234
|
+
|
235
|
+
@volume_id, @file_index, @num_links = Kernel32.get_stat_shared(path)
|
111
236
|
end
|
112
237
|
|
113
238
|
# @!visibility private
|
@@ -129,27 +254,18 @@ module Recls
|
|
129
254
|
# @!visibility private
|
130
255
|
def initialize(path) # :nodoc:
|
131
256
|
|
132
|
-
|
133
|
-
|
134
|
-
# for some reason not forcing this new string causes 'can't modify frozen string (TypeError)'
|
135
|
-
attributes = GetFileAttributes.call("#{path}")
|
257
|
+
path = path.to_str
|
136
258
|
|
137
|
-
|
259
|
+
@path = path
|
138
260
|
|
139
|
-
|
140
|
-
else
|
141
|
-
|
142
|
-
@attributes = attributes
|
143
|
-
end
|
261
|
+
@attributes = Kernel32.get_file_attributes(path)
|
144
262
|
|
145
263
|
super(path)
|
146
264
|
|
147
265
|
@by_handle_information = ByHandleInformation.new(path)
|
148
266
|
|
149
|
-
|
150
|
-
|
151
|
-
n = GetShortPathName.call("#{path}", buff, buff.length)
|
152
|
-
@short_path = (0 == n) ? nil : buff[0...n]
|
267
|
+
@short_path = Kernel32.get_short_path_name(path)
|
268
|
+
|
153
269
|
end
|
154
270
|
|
155
271
|
public
|
@@ -165,7 +281,7 @@ module Recls
|
|
165
281
|
# @!visibility private
|
166
282
|
def hidden? # :nodoc:
|
167
283
|
|
168
|
-
|
284
|
+
has_attribute_? FILE_ATTRIBUTE_HIDDEN
|
169
285
|
end
|
170
286
|
|
171
287
|
# Windows-specific attributes
|
@@ -215,7 +331,7 @@ module Recls
|
|
215
331
|
|
216
332
|
public
|
217
333
|
# @!visibility private
|
218
|
-
def
|
334
|
+
def self.stat(path) # :nodoc:
|
219
335
|
|
220
336
|
Recls::Ximpl::FileStat.new(path)
|
221
337
|
end
|
data/test/unit/tc_recls_entry.rb
CHANGED
@@ -19,7 +19,7 @@ class Test_Recls_entry < Test::Unit::TestCase
|
|
19
19
|
|
20
20
|
def setup
|
21
21
|
|
22
|
-
@cwd = Dir.pwd
|
22
|
+
@cwd = Dir.pwd.freeze
|
23
23
|
end
|
24
24
|
|
25
25
|
def test_entry_does_not_mark_directory
|
@@ -51,5 +51,22 @@ class Test_Recls_entry < Test::Unit::TestCase
|
|
51
51
|
|
52
52
|
assert_not_equal cwd.object_id, cwd2.object_id
|
53
53
|
end
|
54
|
+
|
55
|
+
if Recls.windows?
|
56
|
+
|
57
|
+
def test_entry_file_short_name
|
58
|
+
|
59
|
+
cwd = Recls.stat @cwd
|
60
|
+
|
61
|
+
if cwd.file_short_name
|
62
|
+
|
63
|
+
if cwd.file_full_name != cwd.file_short_name
|
64
|
+
|
65
|
+
assert cwd.file_short_name =~ /^.{0,8}\..{0,3}$/, "'#{cwd.file_short_name}' does not match expected 8.3 form"
|
66
|
+
assert_equal cwd.file_short_name.upcase, cwd.file_short_name, "'#{cwd.file_short_name}' is not uppercase as expected"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
54
71
|
end
|
55
72
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: recls-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.13.
|
4
|
+
version: 2.13.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Wilson
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: xqsr3
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
version: '0.31'
|
27
27
|
description: 'RECursive LS for Ruby
|
28
28
|
|
29
|
-
'
|
29
|
+
'
|
30
30
|
email: matthew@synesis.com.au
|
31
31
|
executables: []
|
32
32
|
extensions: []
|
@@ -83,7 +83,7 @@ homepage: http://github.com/synesissoftware/recls.Ruby
|
|
83
83
|
licenses:
|
84
84
|
- BSD-3-Clause
|
85
85
|
metadata: {}
|
86
|
-
post_install_message:
|
86
|
+
post_install_message:
|
87
87
|
rdoc_options: []
|
88
88
|
require_paths:
|
89
89
|
- lib
|
@@ -98,8 +98,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
98
|
- !ruby/object:Gem::Version
|
99
99
|
version: '0'
|
100
100
|
requirements: []
|
101
|
-
rubygems_version: 3.
|
102
|
-
signing_key:
|
101
|
+
rubygems_version: 3.3.7
|
102
|
+
signing_key:
|
103
103
|
specification_version: 4
|
104
104
|
summary: recls.Ruby
|
105
105
|
test_files: []
|