ffi-libarchive 0.4.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd86d5c024c71eab9c05b65c2a650423acf6e082f09e65167b87a07c2ec9c6d5
4
- data.tar.gz: b4ee964dc4caa87255c2f4ca6eedd43e6a962112f9481696ead94314bd7c482f
3
+ metadata.gz: 7a37a59bb2528341adba957354cc76a776d726a715390e6fa2261b9effcca7ca
4
+ data.tar.gz: 3e94f65843192c53a13352c0790833aad2e2deea833b6d97e68e068ffc5c2bef
5
5
  SHA512:
6
- metadata.gz: 35e0e854d76bd8d579c2c3626a62474a7bd735df3f30f294068d0864c396d93957d3cba73b0fd4880c9e3035aca45aa31611e5ebdc9b9c73c68be5816b3cdb38
7
- data.tar.gz: bb5610e6b77babfb94d535248de078674a5697cfcac3a0d37882da27455c9c7440f404d69127171628ec4ae320182d6ef34bc877a96957545593628545a8457c
6
+ metadata.gz: dddc27a6897a12278ef644b124c9f3e718cb837fba7e2b164cc4766041b8063139be1836525bbcfa7a13cd1be8637155c6a96a470cc4ada3448482cb2db9c14b
7
+ data.tar.gz: b2d00c86cd4563a8bc86b6bad28f7d07a6e4c90281f074866fe30a330a2b4697c5321e9708777ad429f4e779a467cc45c47f2ff3d0f0b9952cd1d7279296a4b8
@@ -1,7 +1,7 @@
1
1
  module Archive
2
2
  # :stopdoc:
3
- LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
4
- PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
3
+ LIBPATH ||= ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
4
+ PATH ||= ::File.dirname(LIBPATH) + ::File::SEPARATOR
5
5
  # :startdoc:
6
6
 
7
7
  # Returns the library path for the module. If any arguments are given,
@@ -46,7 +46,8 @@ module Archive
46
46
  def self.require_all_libs_relative_to(fname, dir = nil)
47
47
  dir ||= ::File.basename(fname, ".*")
48
48
  search_me = ::File.expand_path(
49
- ::File.join(::File.dirname(fname), dir, "**", "*.rb"))
49
+ ::File.join(::File.dirname(fname), dir, "**", "*.rb")
50
+ )
50
51
 
51
52
  Dir.glob(search_me).sort.each { |rb| require rb }
52
53
  end
@@ -8,7 +8,7 @@ module Archive
8
8
  end
9
9
 
10
10
  extend FFI::Library
11
- ffi_lib %w{libarchive.so.13 libarchive.13 libarchive.so libarchive archive}
11
+ ffi_lib %w{libarchive.so.13 libarchive.13 libarchive-13 libarchive.so libarchive archive}
12
12
 
13
13
  attach_function :archive_version_number, [], :int
14
14
  attach_function :archive_version_string, [], :string
@@ -16,15 +16,24 @@ module Archive
16
16
  attach_function :archive_errno, [:pointer], :int
17
17
 
18
18
  attach_function :archive_read_new, [], :pointer
19
- attach_function :archive_read_open_filename, [:pointer, :string, :size_t], :int
20
- attach_function :archive_read_open_memory, [:pointer, :pointer, :size_t], :int
21
- attach_function :archive_read_support_compression_program, [:pointer, :string], :int
19
+ attach_function :archive_read_open_filename, %i{pointer string size_t}, :int
20
+ attach_function :archive_read_open_memory, %i{pointer pointer size_t}, :int
21
+ attach_function :archive_read_open1, [:pointer], :int
22
+ attach_function :archive_read_support_compression_program, %i{pointer string}, :int
22
23
  attach_function :archive_read_support_compression_all, [:pointer], :int
23
24
 
24
- attach_function_maybe :archive_read_set_format, [:pointer, :int], :int
25
- attach_function_maybe :archive_read_append_filter, [:pointer, :int], :int
26
- attach_function_maybe :archive_read_append_filter_program, [:pointer, :pointer], :int
27
- attach_function_maybe :archive_read_append_filter_program_signature, [:pointer, :string, :pointer, :size_t], :int
25
+ callback :archive_read_callback, %i{pointer pointer pointer}, :int
26
+ callback :archive_skip_callback, %i{pointer pointer int64}, :int
27
+ callback :archive_seek_callback, %i{pointer pointer int64 int}, :int
28
+ attach_function :archive_read_set_read_callback, %i{pointer archive_read_callback}, :int
29
+ attach_function :archive_read_set_callback_data, %i{pointer pointer}, :int
30
+ attach_function :archive_read_set_skip_callback, %i{pointer archive_skip_callback}, :int
31
+ attach_function :archive_read_set_seek_callback, %i{pointer archive_seek_callback}, :int
32
+
33
+ attach_function_maybe :archive_read_set_format, %i{pointer int}, :int
34
+ attach_function_maybe :archive_read_append_filter, %i{pointer int}, :int
35
+ attach_function_maybe :archive_read_append_filter_program, %i{pointer pointer}, :int
36
+ attach_function_maybe :archive_read_append_filter_program_signature, %i{pointer string pointer size_t}, :int
28
37
 
29
38
  attach_function_maybe :archive_read_support_filter_all, [:pointer], :int
30
39
  attach_function_maybe :archive_read_support_filter_bzip2, [:pointer], :int
@@ -64,18 +73,18 @@ module Archive
64
73
  attach_function_maybe :archive_read_support_format_zip_seekable, [:pointer], :int
65
74
 
66
75
  attach_function :archive_read_finish, [:pointer], :int
67
- attach_function :archive_read_extract, [:pointer, :pointer, :int], :int
76
+ attach_function :archive_read_extract, %i{pointer pointer int}, :int
68
77
  attach_function :archive_read_header_position, [:pointer], :int
69
- attach_function :archive_read_next_header, [:pointer, :pointer], :int
70
- attach_function :archive_read_data, [:pointer, :pointer, :size_t], :size_t
71
- attach_function :archive_read_data_into_fd, [:pointer, :int], :int
78
+ attach_function :archive_read_next_header, %i{pointer pointer}, :int
79
+ attach_function :archive_read_data, %i{pointer pointer size_t}, :size_t
80
+ attach_function :archive_read_data_into_fd, %i{pointer int}, :int
72
81
 
73
82
  attach_function :archive_write_new, [], :pointer
74
- attach_function :archive_write_open_filename, [:pointer, :string], :int
75
- callback :archive_open_callback, [:pointer, :pointer], :int
76
- callback :archive_write_callback, [:pointer, :pointer, :pointer, :size_t], :int
77
- callback :archive_close_callback, [:pointer, :pointer], :int
78
- attach_function :archive_write_open, [:pointer, :pointer, :pointer, :archive_write_callback, :pointer], :int
83
+ attach_function :archive_write_open_filename, %i{pointer string}, :int
84
+ callback :archive_open_callback, %i{pointer pointer}, :int
85
+ callback :archive_write_callback, %i{pointer pointer pointer size_t}, :int
86
+ callback :archive_close_callback, %i{pointer pointer}, :int
87
+ attach_function :archive_write_open, %i{pointer pointer pointer archive_write_callback pointer}, :int
79
88
  attach_function :archive_write_set_compression_none, [:pointer], :int
80
89
  attach_function_maybe :archive_write_set_compression_gzip, [:pointer], :int
81
90
  attach_function_maybe :archive_write_set_compression_bzip2, [:pointer], :int
@@ -83,7 +92,7 @@ module Archive
83
92
  attach_function_maybe :archive_write_set_compression_compress, [:pointer], :int
84
93
  attach_function_maybe :archive_write_set_compression_lzma, [:pointer], :int
85
94
  attach_function_maybe :archive_write_set_compression_xz, [:pointer], :int
86
- attach_function :archive_write_set_compression_program, [:pointer, :string], :int
95
+ attach_function :archive_write_set_compression_program, %i{pointer string}, :int
87
96
 
88
97
  def self.archive_write_set_compression(archive, compression)
89
98
  case compression
@@ -106,94 +115,95 @@ module Archive
106
115
  end
107
116
  end
108
117
 
109
- attach_function :archive_write_set_format, [:pointer, :int], :int
110
- attach_function :archive_write_data, [:pointer, :pointer, :size_t], :ssize_t
111
- attach_function :archive_write_header, [:pointer, :pointer], :int
118
+ attach_function :archive_write_set_format, %i{pointer int}, :int
119
+ attach_function :archive_write_data, %i{pointer pointer size_t}, :ssize_t
120
+ attach_function :archive_write_header, %i{pointer pointer}, :int
112
121
  attach_function :archive_write_finish, [:pointer], :void
113
122
  attach_function :archive_write_get_bytes_in_last_block, [:pointer], :int
114
- attach_function :archive_write_set_bytes_in_last_block, [:pointer, :int], :int
123
+ attach_function :archive_write_set_bytes_in_last_block, %i{pointer int}, :int
115
124
 
116
125
  attach_function :archive_entry_new, [], :pointer
126
+ attach_function :archive_entry_clone, [:pointer], :pointer
117
127
  attach_function :archive_entry_free, [:pointer], :void
118
128
  attach_function :archive_entry_atime, [:pointer], :time_t
119
- attach_function :archive_entry_atime_nsec, [:pointer, :time_t, :long], :void
129
+ attach_function :archive_entry_atime_nsec, %i{pointer time_t long}, :void
120
130
  attach_function_maybe :archive_entry_atime_is_set, [:pointer], :int
121
- attach_function :archive_entry_set_atime, [:pointer, :time_t, :long], :int
131
+ attach_function :archive_entry_set_atime, %i{pointer time_t long}, :int
122
132
  attach_function_maybe :archive_entry_unset_atime, [:pointer], :int
123
133
  attach_function_maybe :archive_entry_birthtime, [:pointer], :time_t
124
- attach_function_maybe :archive_entry_birthtime_nsec, [:pointer, :time_t, :long], :void
134
+ attach_function_maybe :archive_entry_birthtime_nsec, %i{pointer time_t long}, :void
125
135
  attach_function_maybe :archive_entry_birthtime_is_set, [:pointer], :int
126
- attach_function_maybe :archive_entry_set_birthtime, [:pointer, :time_t, :long], :int
136
+ attach_function_maybe :archive_entry_set_birthtime, %i{pointer time_t long}, :int
127
137
  attach_function_maybe :archive_entry_unset_birthtime, [:pointer], :int
128
138
  attach_function :archive_entry_ctime, [:pointer], :time_t
129
- attach_function :archive_entry_ctime_nsec, [:pointer, :time_t, :long], :void
139
+ attach_function :archive_entry_ctime_nsec, %i{pointer time_t long}, :void
130
140
  attach_function_maybe :archive_entry_ctime_is_set, [:pointer], :int
131
- attach_function :archive_entry_set_ctime, [:pointer, :time_t, :long], :int
141
+ attach_function :archive_entry_set_ctime, %i{pointer time_t long}, :int
132
142
  attach_function_maybe :archive_entry_unset_ctime, [:pointer], :int
133
143
  attach_function :archive_entry_mtime, [:pointer], :time_t
134
- attach_function :archive_entry_mtime_nsec, [:pointer, :time_t, :long], :void
144
+ attach_function :archive_entry_mtime_nsec, %i{pointer time_t long}, :void
135
145
  attach_function_maybe :archive_entry_mtime_is_set, [:pointer], :int
136
- attach_function :archive_entry_set_mtime, [:pointer, :time_t, :long], :int
146
+ attach_function :archive_entry_set_mtime, %i{pointer time_t long}, :int
137
147
  attach_function_maybe :archive_entry_unset_mtime, [:pointer], :int
138
148
  attach_function :archive_entry_dev, [:pointer], :dev_t
139
- attach_function :archive_entry_set_dev, [:pointer, :dev_t], :void
149
+ attach_function :archive_entry_set_dev, %i{pointer dev_t}, :void
140
150
  attach_function :archive_entry_devmajor, [:pointer], :dev_t
141
- attach_function :archive_entry_set_devmajor, [:pointer, :dev_t], :void
151
+ attach_function :archive_entry_set_devmajor, %i{pointer dev_t}, :void
142
152
  attach_function :archive_entry_devminor, [:pointer], :dev_t
143
- attach_function :archive_entry_set_devminor, [:pointer, :dev_t], :void
153
+ attach_function :archive_entry_set_devminor, %i{pointer dev_t}, :void
144
154
  attach_function :archive_entry_filetype, [:pointer], :mode_t
145
- attach_function :archive_entry_set_filetype, [:pointer, :mode_t], :void
146
- attach_function :archive_entry_fflags, [:pointer, :pointer, :pointer], :void
147
- attach_function :archive_entry_set_fflags, [:pointer, :ulong, :ulong], :void
155
+ attach_function :archive_entry_set_filetype, %i{pointer mode_t}, :void
156
+ attach_function :archive_entry_fflags, %i{pointer pointer pointer}, :void
157
+ attach_function :archive_entry_set_fflags, %i{pointer ulong ulong}, :void
148
158
  attach_function :archive_entry_fflags_text, [:pointer], :string
149
- attach_function :archive_entry_gid, [:pointer], :gid_t
150
- attach_function :archive_entry_set_gid, [:pointer, :gid_t], :void
159
+ attach_function :archive_entry_gid, [:pointer], :uint
160
+ attach_function :archive_entry_set_gid, %i{pointer uint}, :void
151
161
  attach_function :archive_entry_gname, [:pointer], :string
152
- attach_function :archive_entry_set_gname, [:pointer, :string], :void
162
+ attach_function :archive_entry_set_gname, %i{pointer string}, :void
153
163
  attach_function :archive_entry_hardlink, [:pointer], :string
154
- attach_function :archive_entry_set_hardlink, [:pointer, :string], :void
155
- attach_function :archive_entry_set_link, [:pointer, :string], :void
164
+ attach_function :archive_entry_set_hardlink, %i{pointer string}, :void
165
+ attach_function :archive_entry_set_link, %i{pointer string}, :void
156
166
  attach_function :archive_entry_ino, [:pointer], :ino_t
157
- attach_function :archive_entry_set_ino, [:pointer, :ino_t], :void
167
+ attach_function :archive_entry_set_ino, %i{pointer ino_t}, :void
158
168
  attach_function :archive_entry_mode, [:pointer], :mode_t
159
- attach_function :archive_entry_set_mode, [:pointer, :mode_t], :void
160
- attach_function :archive_entry_set_perm, [:pointer, :mode_t], :void
169
+ attach_function :archive_entry_set_mode, %i{pointer mode_t}, :void
170
+ attach_function :archive_entry_set_perm, %i{pointer mode_t}, :void
161
171
  attach_function :archive_entry_nlink, [:pointer], :uint
162
- attach_function :archive_entry_set_nlink, [:pointer, :uint], :void
172
+ attach_function :archive_entry_set_nlink, %i{pointer uint}, :void
163
173
  attach_function :archive_entry_pathname, [:pointer], :string
164
- attach_function :archive_entry_set_pathname, [:pointer, :string], :void
174
+ attach_function :archive_entry_set_pathname, %i{pointer string}, :void
165
175
  attach_function :archive_entry_rdev, [:pointer], :dev_t
166
- attach_function :archive_entry_set_rdev, [:pointer, :dev_t], :void
176
+ attach_function :archive_entry_set_rdev, %i{pointer dev_t}, :void
167
177
  attach_function :archive_entry_rdevmajor, [:pointer], :dev_t
168
- attach_function :archive_entry_set_rdevmajor, [:pointer, :dev_t], :void
178
+ attach_function :archive_entry_set_rdevmajor, %i{pointer dev_t}, :void
169
179
  attach_function :archive_entry_rdevminor, [:pointer], :dev_t
170
- attach_function :archive_entry_set_rdevminor, [:pointer, :dev_t], :void
180
+ attach_function :archive_entry_set_rdevminor, %i{pointer dev_t}, :void
171
181
  attach_function :archive_entry_size, [:pointer], :int64_t
172
- attach_function :archive_entry_set_size, [:pointer, :int64_t], :void
182
+ attach_function :archive_entry_set_size, %i{pointer int64_t}, :void
173
183
  attach_function_maybe :archive_entry_unset_size, [:pointer], :void
174
184
  attach_function_maybe :archive_entry_size_is_set, [:pointer], :int
175
185
  attach_function :archive_entry_sourcepath, [:pointer], :string
176
186
  attach_function :archive_entry_strmode, [:pointer], :string
177
187
  attach_function :archive_entry_symlink, [:pointer], :string
178
- attach_function :archive_entry_set_symlink, [:pointer, :string], :void
179
- attach_function :archive_entry_uid, [:pointer], :uid_t
180
- attach_function :archive_entry_set_uid, [:pointer, :uid_t], :void
188
+ attach_function :archive_entry_set_symlink, %i{pointer string}, :void
189
+ attach_function :archive_entry_uid, [:pointer], :uint
190
+ attach_function :archive_entry_set_uid, %i{pointer uint}, :void
181
191
  attach_function :archive_entry_uname, [:pointer], :string
182
- attach_function :archive_entry_set_uname, [:pointer, :string], :void
183
- attach_function :archive_entry_copy_stat, [:pointer, :pointer], :void
184
- attach_function :archive_entry_copy_fflags_text, [:pointer, :string], :string
185
- attach_function :archive_entry_copy_gname, [:pointer, :string], :string
186
- attach_function :archive_entry_copy_uname, [:pointer, :string], :string
187
- attach_function :archive_entry_copy_hardlink, [:pointer, :string], :string
188
- attach_function :archive_entry_copy_link, [:pointer, :string], :string
189
- attach_function :archive_entry_copy_symlink, [:pointer, :string], :string
190
- attach_function :archive_entry_copy_sourcepath, [:pointer, :string], :string
191
- attach_function :archive_entry_copy_pathname, [:pointer, :string], :string
192
+ attach_function :archive_entry_set_uname, %i{pointer string}, :void
193
+ attach_function :archive_entry_copy_stat, %i{pointer pointer}, :void
194
+ attach_function :archive_entry_copy_fflags_text, %i{pointer string}, :string
195
+ attach_function :archive_entry_copy_gname, %i{pointer string}, :string
196
+ attach_function :archive_entry_copy_uname, %i{pointer string}, :string
197
+ attach_function :archive_entry_copy_hardlink, %i{pointer string}, :string
198
+ attach_function :archive_entry_copy_link, %i{pointer string}, :string
199
+ attach_function :archive_entry_copy_symlink, %i{pointer string}, :string
200
+ attach_function :archive_entry_copy_sourcepath, %i{pointer string}, :string
201
+ attach_function :archive_entry_copy_pathname, %i{pointer string}, :string
192
202
  attach_function :archive_entry_xattr_clear, [:pointer], :void
193
- attach_function :archive_entry_xattr_add_entry, [:pointer, :string, :pointer, :size_t], :void
203
+ attach_function :archive_entry_xattr_add_entry, %i{pointer string pointer size_t}, :void
194
204
  attach_function :archive_entry_xattr_count, [:pointer], :int
195
205
  attach_function :archive_entry_xattr_reset, [:pointer], :int
196
- attach_function :archive_entry_xattr_next, [:pointer, :pointer, :pointer, :pointer], :int
206
+ attach_function :archive_entry_xattr_next, %i{pointer pointer pointer pointer}, :int
197
207
 
198
208
  EOF = 1
199
209
  OK = 0
@@ -278,6 +288,10 @@ module Archive
278
288
  Reader.open_memory string, command, &block
279
289
  end
280
290
 
291
+ def self.read_open_stream(reader, &block)
292
+ Reader.open_stream reader, &block
293
+ end
294
+
281
295
  def self.write_open_filename(file_name, compression, format, &block)
282
296
  Writer.open_filename file_name, compression, format, &block
283
297
  end
@@ -336,6 +350,7 @@ module Archive
336
350
 
337
351
  def archive
338
352
  raise Error, "No archive open" unless @archive
353
+
339
354
  @archive
340
355
  end
341
356
  protected :archive
@@ -17,14 +17,14 @@ module Archive
17
17
  CHARACTER_SPECIAL = 0020000 # character device
18
18
  FIFO = 0010000 # FIFO
19
19
 
20
- def self.from_pointer(entry)
21
- new entry
20
+ def self.from_pointer(entry, clone: false)
21
+ new entry, clone: clone
22
22
  end
23
23
 
24
- def initialize(entry = nil)
24
+ def initialize(entry = nil, clone: false)
25
25
  @entry_free = [true]
26
26
  if entry
27
- @entry = entry
27
+ @entry = clone ? C.archive_entry_clone(entry) : entry
28
28
  yield self if block_given?
29
29
  else
30
30
  @entry = C.archive_entry_new
@@ -34,7 +34,7 @@ module Archive
34
34
  result = yield self
35
35
  C.archive_entry_free(@entry)
36
36
  @entry = nil
37
- return result
37
+ result
38
38
  else
39
39
  @entry_free[0] = false
40
40
  ObjectSpace.define_finalizer(self, Entry.finalizer(@entry, @entry_free))
@@ -60,6 +60,7 @@ module Archive
60
60
 
61
61
  def entry
62
62
  raise "No entry object" unless @entry
63
+
63
64
  @entry
64
65
  end
65
66
 
@@ -182,6 +183,7 @@ module Archive
182
183
 
183
184
  stat = Archive::Stat.ffi_libarchive_create_lstat(filename)
184
185
  raise Error, "Copy stat failed: #{Archive::Stat.ffi_error}" if stat.null?
186
+
185
187
  C.archive_entry_copy_stat(entry, stat)
186
188
  ensure
187
189
  Archive::Stat.ffi_libarchive_free_stat(stat)
@@ -207,6 +209,7 @@ module Archive
207
209
 
208
210
  stat = Archive::Stat.ffi_libarchive_create_stat(filename)
209
211
  raise Error, "Copy stat failed: #{Archive::Stat.ffi_error}" if stat.null?
212
+
210
213
  C.archive_entry_copy_stat(entry, stat)
211
214
  ensure
212
215
  Archive::Stat.ffi_libarchive_free_stat(stat)
@@ -459,10 +462,10 @@ module Archive
459
462
  value = FFI::MemoryPointer.new :pointer
460
463
  size = FFI::MemoryPointer.new :size_t
461
464
  if C.archive_entry_xattr_next(entry, name, value, size) != C::OK
462
- return nil
465
+ nil
463
466
  else
464
467
  # TODO: someday size.read_size_t could work
465
- return [name.null? ? nil : name.read_string,
468
+ [name.null? ? nil : name.read_string,
466
469
  value.null? ? nil : value.get_string(0, size.read_ulong)]
467
470
  end
468
471
  end
@@ -28,6 +28,19 @@ module Archive
28
28
  end
29
29
  end
30
30
 
31
+ def self.open_stream(reader)
32
+ if block_given?
33
+ reader = new reader: reader
34
+ begin
35
+ yield reader
36
+ ensure
37
+ reader.close
38
+ end
39
+ else
40
+ new reader: reader
41
+ end
42
+ end
43
+
31
44
  def initialize(params = {})
32
45
  super C.method(:archive_read_new), C.method(:archive_read_finish)
33
46
 
@@ -40,13 +53,44 @@ module Archive
40
53
 
41
54
  raise Error, @archive if C.archive_read_support_format_all(archive) != C::OK
42
55
 
43
- if params[:file_name]
56
+ case
57
+ when params[:file_name]
44
58
  raise Error, @archive if C.archive_read_open_filename(archive, params[:file_name], 1024) != C::OK
45
- elsif params[:memory]
59
+ when params[:memory]
46
60
  str = params[:memory]
47
61
  @data = FFI::MemoryPointer.new(str.bytesize + 1)
48
62
  @data.write_string str, str.bytesize
49
63
  raise Error, @archive if C.archive_read_open_memory(archive, @data, str.bytesize) != C::OK
64
+ when params[:reader]
65
+ @reader = params[:reader]
66
+ @buffer = nil
67
+
68
+ @read_callback = FFI::Function.new(:int, %i{pointer pointer pointer}) do |_, _, archive_data|
69
+ data = @reader.call || ""
70
+ @buffer = FFI::MemoryPointer.new(:char, data.size) if @buffer.nil? || @buffer.size < data.size
71
+ @buffer.write_bytes(data)
72
+ archive_data.write_pointer(@buffer)
73
+ data.size
74
+ end
75
+ C.archive_read_set_read_callback(archive, @read_callback)
76
+
77
+ if @reader.respond_to?(:skip)
78
+ @skip_callback = FFI::Function.new(:int, %i{pointer pointer int64}) do |_, _, offset|
79
+ @reader.skip(offset)
80
+ end
81
+ C.archive_read_set_skip_callback(archive, @skip_callback)
82
+ end
83
+
84
+ if @reader.respond_to?(:seek)
85
+ @seek_callback = FFI::Function.new(:int, %i{pointer pointer int64 int}) do |_, _, offset, whence|
86
+ @reader.seek(offset, whence)
87
+ end
88
+ C.archive_read_set_seek_callback(archive, @seek_callback)
89
+ end
90
+
91
+ # Required or open1 will segfault, even though the callback data is not used.
92
+ C.archive_read_set_callback_data(archive, nil)
93
+ raise Error, @archive if C.archive_read_open1(archive) != C::OK
50
94
  end
51
95
  rescue
52
96
  close
@@ -65,11 +109,11 @@ module Archive
65
109
  raise Error, @archive if C.archive_read_header_position archive
66
110
  end
67
111
 
68
- def next_header
112
+ def next_header(clone_entry: false)
69
113
  entry_ptr = FFI::MemoryPointer.new(:pointer)
70
114
  case C.archive_read_next_header(archive, entry_ptr)
71
115
  when C::OK
72
- Entry.from_pointer entry_ptr.read_pointer
116
+ Entry.from_pointer entry_ptr.read_pointer, clone: clone_entry
73
117
  when C::EOF
74
118
  @eof = true
75
119
  nil
@@ -1,3 +1,3 @@
1
1
  module Archive
2
- VERSION = "0.4.2".freeze
2
+ VERSION = "1.0.3".freeze
3
3
  end
@@ -58,9 +58,9 @@ module Archive
58
58
  end
59
59
  @data = write_callback params[:memory]
60
60
  raise Error, @archive if C.archive_write_open(archive, nil,
61
- nil,
62
- @data,
63
- nil) != C::OK
61
+ nil,
62
+ @data,
63
+ nil) != C::OK
64
64
  end
65
65
  rescue
66
66
  close
@@ -117,10 +117,12 @@ module Archive
117
117
  if (n = C.archive_write_data(ar, str, str.bytesize)) < 1
118
118
  return len
119
119
  end
120
+
120
121
  len += n
121
122
  end
122
123
  else
123
124
  raise ArgumentError, "wrong number of argument (#{args.size}) for 1)" if args.size != 1
125
+
124
126
  str = args[0]
125
127
  C.archive_write_data(archive, str, str.bytesize)
126
128
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi-libarchive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Bellone
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2018-07-21 00:00:00.000000000 Z
13
+ date: 2020-06-26 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: ffi
@@ -40,34 +40,6 @@ dependencies:
40
40
  - - ">="
41
41
  - !ruby/object:Gem::Version
42
42
  version: '0'
43
- - !ruby/object:Gem::Dependency
44
- name: rake
45
- requirement: !ruby/object:Gem::Requirement
46
- requirements:
47
- - - ">="
48
- - !ruby/object:Gem::Version
49
- version: '0'
50
- type: :development
51
- prerelease: false
52
- version_requirements: !ruby/object:Gem::Requirement
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- version: '0'
57
- - !ruby/object:Gem::Dependency
58
- name: test-unit
59
- requirement: !ruby/object:Gem::Requirement
60
- requirements:
61
- - - ">="
62
- - !ruby/object:Gem::Version
63
- version: '0'
64
- type: :development
65
- prerelease: false
66
- version_requirements: !ruby/object:Gem::Requirement
67
- requirements:
68
- - - ">="
69
- - !ruby/object:Gem::Version
70
- version: '0'
71
43
  description: A Ruby FFI binding to libarchive.
72
44
  email:
73
45
  - jbellone@bloomberg.net
@@ -77,12 +49,7 @@ executables: []
77
49
  extensions: []
78
50
  extra_rdoc_files: []
79
51
  files:
80
- - Gemfile
81
52
  - LICENSE
82
- - README.md
83
- - Rakefile
84
- - VERSION
85
- - ffi-libarchive.gemspec
86
53
  - lib/ffi-libarchive.rb
87
54
  - lib/ffi-libarchive/archive.rb
88
55
  - lib/ffi-libarchive/entry.rb
@@ -90,10 +57,6 @@ files:
90
57
  - lib/ffi-libarchive/stat.rb
91
58
  - lib/ffi-libarchive/version.rb
92
59
  - lib/ffi-libarchive/writer.rb
93
- - test/data/test.tar.gz
94
- - test/sets/ts_read.rb
95
- - test/sets/ts_write.rb
96
- - test/test_ffi-libarchive.rb
97
60
  homepage: https://github.com/chef/ffi-libarchive
98
61
  licenses:
99
62
  - Apache-2.0
@@ -113,8 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
76
  - !ruby/object:Gem::Version
114
77
  version: '0'
115
78
  requirements: []
116
- rubyforge_project:
117
- rubygems_version: 2.7.6
79
+ rubygems_version: 3.0.3
118
80
  signing_key:
119
81
  specification_version: 4
120
82
  summary: A Ruby FFI binding to libarchive.
data/Gemfile DELETED
@@ -1,10 +0,0 @@
1
- source "https://rubygems.org"
2
- gemspec
3
-
4
- group :lint do
5
- gem "chefstyle"
6
- end
7
-
8
- group :doc do
9
- gem "yard"
10
- end
data/README.md DELETED
@@ -1,77 +0,0 @@
1
- ffi-libarchive
2
- ==============
3
- A Ruby FFI binding to [libarchive][0].
4
-
5
- This library provides Ruby FFI bindings to the well-known
6
- [libarchive library][0].
7
-
8
- ## Installation
9
-
10
- Ensure that you have libarchive installed. On Debian/Ubuntu:
11
-
12
- ```sh
13
- apt install libarchive13
14
- ```
15
-
16
- On macOS with Homebrew:
17
- ```sh
18
- brew install libarchive
19
- ```
20
-
21
- Add this line to your application's Gemfile:
22
-
23
- ```ruby
24
- gem 'ffi-libarchive'
25
- ```
26
-
27
- And then execute:
28
-
29
- ```shell
30
- $ bundle
31
- ```
32
-
33
- Or install it yourself as:
34
-
35
- ```shell
36
- $ gem install ffi-libarchive
37
- ```
38
-
39
- ## Usage
40
-
41
- To extract an archive into the current directory:
42
-
43
- ```ruby
44
- flags = Archive::EXTRACT_PERM
45
- reader = Archive::Reader.open_filename('/path/to/archive.tgz')
46
-
47
- reader.each_entry do |entry|
48
- reader.extract(entry, flags.to_i)
49
- end
50
- reader.close
51
- ```
52
-
53
- To create a gzipped tar archive:
54
-
55
- ```ruby
56
- Archive.write_open_filename('my.tgz', Archive::COMPRESSION_GZIP, Archive::FORMAT_TAR_PAX_RESTRICTED) do |tar|
57
- content = File.read 'some_path'
58
- size = content.size
59
- tar.new_entry do |e|
60
- e.pathname = 'some_path'
61
- e.size = size
62
- e.filetype = Archive::Entry::FILE
63
- tar.write_header e
64
- tar.write_data content
65
- end
66
- end
67
- ```
68
-
69
- ## Contributing
70
-
71
- Bug reports and pull requests are welcome on GitHub at <https://github.com/chef/ffi-libarchive>. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Community Guidelines](https://docs.chef.io/community_guidelines.html) code of conduct.
72
-
73
- ## License
74
-
75
- The gem is available as open source under the terms of the Apache License, v2
76
-
77
- [0]: https://github.com/libarchive/libarchive
data/Rakefile DELETED
@@ -1,28 +0,0 @@
1
- #!/usr/bin/env rake
2
-
3
- require "bundler/setup"
4
- require "bundler/gem_tasks"
5
- require "chefstyle"
6
- require "rubocop/rake_task"
7
- require "rake/testtask"
8
-
9
- namespace :style do
10
- desc "Run Ruby style checks"
11
- RuboCop::RakeTask.new(:ruby)
12
- end
13
-
14
- Rake::TestTask.new(:test) do |t|
15
- t.libs << "test"
16
- t.libs << "lib"
17
- t.test_files = FileList["test/test_ffi-libarchive.rb"]
18
- end
19
-
20
- desc "Run all style checks"
21
- task style: ["style:ruby"]
22
-
23
- desc "Run style & unit tests on Travis"
24
- task travis: %w{style test}
25
-
26
- # Default
27
- desc "Run style, unit"
28
- task default: %w{style test}
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.4.2
@@ -1,25 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path("../lib", __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "ffi-libarchive/version"
5
-
6
- Gem::Specification.new do |s|
7
- s.name = "ffi-libarchive"
8
- s.version = Archive::VERSION
9
- s.authors = ["John Bellone", "Jamie Winsor", "Frank Fischer"]
10
- s.email = %w{jbellone@bloomberg.net jamie@vialstudios.com frank-fischer@shadow-soft.de}
11
- s.description = "A Ruby FFI binding to libarchive."
12
- s.summary = s.description
13
- s.homepage = "https://github.com/chef/ffi-libarchive"
14
- s.license = "Apache-2.0"
15
-
16
- s.files = %w{ Gemfile Rakefile README.md LICENSE VERSION } + Dir.glob("{lib,test}/**/*", File::FNM_DOTMATCH).reject { |f| File.directory?(f) } + Dir.glob("*.gemspec")
17
- s.require_paths = %w{lib}
18
- s.required_ruby_version = ">= 2.4.0"
19
-
20
- s.add_dependency "ffi", "~> 1.0"
21
-
22
- s.add_development_dependency "bundler"
23
- s.add_development_dependency "rake"
24
- s.add_development_dependency "test-unit"
25
- end
Binary file
@@ -1,144 +0,0 @@
1
- require "ffi-libarchive"
2
- require "tmpdir"
3
- require "test/unit"
4
-
5
- class TS_ReadArchive < Test::Unit::TestCase
6
-
7
- CONTENT_SPEC =
8
- [
9
- ["test/", "directory", 0755, nil ],
10
- ["test/b/", "directory", 0755, nil ],
11
- ["test/b/c/", "directory", 0755, nil ],
12
- ["test/b/c/c.dat", "file", 0600, "\266\262\v_\266\243\305\3601\204\277\351\354\265\003\036\036\365f\377\210\205\032\222\346\370b\360u\032Y\301".b ],
13
- ["test/b/c/d/", "directory", 0711, nil ],
14
- ["test/b/c/d/d.dat", "symbolic_link", 0777, "../c.dat" ],
15
- ["test/b/b.dat", "file", 0640, "s&\245\354(M\331=\270\000!s\355\240\252\355'N\304\343\bY\317\t\274\210\3128\321\347\234!".b ],
16
- ["test/a.dat", "file", 0777, "\021\216\231Y\354\236\271\372\336\213\224R\211{D{\277\262\304\211xu\330\\\275@~\035\vSRM".b ]
17
- ]
18
-
19
- def setup
20
- File.open("data/test.tar.gz", "rb") do |f|
21
- @archive_content = f.read
22
- end
23
- end
24
-
25
- def test_read_tar_gz_from_file
26
- Archive.read_open_filename("data/test.tar.gz") do |ar|
27
- verify_content(ar)
28
- end
29
- end
30
-
31
- def test_read_tar_gz_from_file_with_external_gunzip
32
- Archive.read_open_filename("data/test.tar.gz", "gunzip") do |ar|
33
- verify_content(ar)
34
- end
35
- end
36
-
37
- def test_read_tar_gz_from_memory
38
- Archive.read_open_memory(@archive_content) do |ar|
39
- verify_content(ar)
40
- end
41
- end
42
-
43
- def test_read_tar_gz_from_memory_with_external_gunzip
44
- Archive.read_open_memory(@archive_content, "gunzip") do |ar|
45
- verify_content(ar)
46
- end
47
- end
48
-
49
- def test_read_entry_bigger_than_internal_buffer
50
- alphabet = "abcdefghijklmnopqrstuvwxyz"
51
- entry_size = 1024 * 4 - 3
52
-
53
- srand
54
- content = ""
55
- 1.upto(entry_size) do |i|
56
- index = rand(alphabet.size)
57
- content += alphabet[index, 1]
58
- end
59
-
60
- Dir.mktmpdir do |dir|
61
- Archive.write_open_filename(dir + "/test.tar.gz",
62
- Archive::COMPRESSION_BZIP2, Archive::FORMAT_TAR) do |ar|
63
- ar.new_entry do |entry|
64
- entry.pathname = "chubby.dat"
65
- entry.mode = 0666
66
- entry.filetype = Archive::Entry::FILE
67
- entry.atime = Time.now.to_i
68
- entry.mtime = Time.now.to_i
69
- entry.size = entry_size
70
- ar.write_header(entry)
71
- ar.write_data(content)
72
- end
73
- end
74
-
75
- Archive.read_open_filename(dir + "/test.tar.gz") do |ar|
76
- ar.next_header
77
- data = ar.read_data
78
-
79
- assert_equal entry_size, data.size
80
- assert_equal content.size, data.size
81
- assert_equal content, data
82
- end
83
-
84
- Archive.read_open_filename(dir + "/test.tar.gz") do |ar|
85
- ar.next_header
86
- data = ""
87
- ar.read_data(128) { |chunk| data += chunk }
88
-
89
- assert_equal content, data
90
- end
91
- end
92
- end
93
-
94
- def test_extract_no_additional_flags
95
- Dir.mktmpdir do |dir|
96
- Archive.read_open_filename("data/test.tar.gz") do |ar|
97
- Dir.chdir(dir) do
98
- ar.each_entry do |e|
99
- ar.extract(e)
100
- assert_not_equal File.mtime(e.pathname), e.mtime
101
- end
102
- end
103
- end
104
- end
105
- end
106
-
107
- def test_extract_extract_time
108
- Dir.mktmpdir do |dir|
109
- Archive.read_open_filename("data/test.tar.gz") do |ar|
110
- Dir.chdir(dir) do
111
- ar.each_entry do |e|
112
- ar.extract(e, Archive::EXTRACT_TIME.to_i)
113
- next if e.directory? || e.symbolic_link?
114
- assert_equal File.mtime(e.pathname), e.mtime
115
- end
116
- end
117
- end
118
- end
119
- end
120
-
121
- private
122
-
123
- def verify_content(ar)
124
- content_spec_idx = 0
125
-
126
- while (entry = ar.next_header)
127
- expect_pathname, expect_type, expect_mode, expect_content = CONTENT_SPEC[content_spec_idx]
128
-
129
- assert_equal expect_pathname, entry.pathname
130
- assert_equal entry.send("#{expect_type}?"), true
131
- assert_equal expect_mode, (entry.mode & 07777)
132
-
133
- if entry.symbolic_link?
134
- assert_equal expect_content, entry.symlink
135
- elsif entry.file?
136
- content = ar.read_data(1024)
137
- assert_equal expect_content, content
138
- end
139
-
140
- content_spec_idx += 1
141
- end
142
- end
143
-
144
- end
@@ -1,123 +0,0 @@
1
- require "ffi-libarchive"
2
- require "tmpdir"
3
- require "test/unit"
4
-
5
- class TS_WriteArchive < Test::Unit::TestCase
6
-
7
- CONTENT_SPEC =
8
- [
9
- ["test/", "directory", 0755, nil ],
10
- ["test/b/", "directory", 0755, nil ],
11
- ["test/b/c/", "directory", 0755, nil ],
12
- ["test/b/c/c.dat", "file", 0600, "\266\262\v_\266\243\305\3601\204\277\351\354\265\003\036\036\365f\377\210\205\032\222\346\370b\360u\032Y\301".b ],
13
- ["test/b/c/d/", "directory", 0711, nil ],
14
- ["test/b/c/d/d.dat", "symbolic_link", 0777, "../c.dat" ],
15
- ["test/b/b.dat", "file", 0640, "s&\245\354(M\331=\270\000!s\355\240\252\355'N\304\343\bY\317\t\274\210\3128\321\347\234!".b ],
16
- ["test/a.dat", "file", 0777, "\021\216\231Y\354\236\271\372\336\213\224R\211{D{\277\262\304\211xu\330\\\275@~\035\vSRM".b ]
17
- ]
18
-
19
- def test_end_to_end_write_read_tar_gz
20
- Dir.mktmpdir do |dir|
21
- Archive.write_open_filename(dir + "/test.tar.gz", :gzip, :tar) do |ar|
22
- write_content(ar)
23
- end
24
-
25
- verify_content(dir + "/test.tar.gz")
26
- end
27
- end
28
-
29
- def test_end_to_end_write_read_memory
30
- memory = ""
31
- Archive.write_open_memory(memory, Archive::COMPRESSION_GZIP, Archive::FORMAT_TAR) do |ar|
32
- write_content ar
33
- end
34
- verify_content_memory(memory)
35
- end
36
-
37
- def test_end_to_end_write_read_tar_gz_with_external_gzip
38
- Dir.mktmpdir do |dir|
39
- Archive.write_open_filename(dir + "/test.tar.gz", "gzip", :tar) do |ar|
40
- write_content(ar)
41
- end
42
-
43
- verify_content(dir + "/test.tar.gz")
44
- end
45
- end
46
-
47
- private
48
-
49
- def write_content(ar)
50
- content_spec_idx = 0
51
-
52
- while content_spec_idx < CONTENT_SPEC.size()
53
- entry_path, entry_type, entry_mode, entry_content = \
54
- CONTENT_SPEC[content_spec_idx]
55
-
56
- ar.new_entry do |entry|
57
- entry.pathname = entry_path
58
- entry.mode = entry_mode
59
- entry.filetype = eval "Archive::Entry::#{entry_type.upcase}" # rubocop:disable Security/Eval
60
- entry.size = entry_content.size if entry_content
61
- entry.symlink = entry_content if entry_type == "symbolic_link"
62
- entry.atime = Time.now.to_i
63
- entry.mtime = Time.now.to_i
64
- ar.write_header(entry)
65
-
66
- if entry_type == "file"
67
- ar.write_data(entry_content)
68
- end
69
- end
70
-
71
- content_spec_idx += 1
72
- end
73
- end
74
-
75
- def verify_content_memory(memory)
76
- Archive.read_open_memory(memory) do |ar|
77
- content_spec_idx = 0
78
-
79
- while (entry = ar.next_header)
80
- expect_pathname, expect_type, expect_mode, expect_content = \
81
- CONTENT_SPEC[content_spec_idx]
82
-
83
- assert_equal expect_pathname, entry.pathname
84
- assert_equal entry.send("#{expect_type}?"), true
85
- assert_equal expect_mode, (entry.mode & 07777)
86
-
87
- if entry.symbolic_link?
88
- assert_equal expect_content, entry.symlink
89
- elsif entry.file?
90
- content = ar.read_data(1024)
91
- assert_equal expect_content, content
92
- end
93
-
94
- content_spec_idx += 1
95
- end
96
- end
97
- end
98
-
99
- def verify_content(filename)
100
- Archive.read_open_filename(filename) do |ar|
101
- content_spec_idx = 0
102
-
103
- while (entry = ar.next_header)
104
- expect_pathname, expect_type, expect_mode, expect_content = \
105
- CONTENT_SPEC[content_spec_idx]
106
-
107
- assert_equal expect_pathname, entry.pathname
108
- assert_equal entry.send("#{expect_type}?"), true
109
- assert_equal expect_mode, (entry.mode & 07777)
110
-
111
- if entry.symbolic_link?
112
- assert_equal expect_content, entry.symlink
113
- elsif entry.file?
114
- content = ar.read_data(1024)
115
- assert_equal expect_content, content
116
- end
117
-
118
- content_spec_idx += 1
119
- end
120
- end
121
- end
122
-
123
- end
@@ -1,8 +0,0 @@
1
-
2
- Dir.chdir File.dirname(__FILE__)
3
-
4
- $LOAD_PATH.unshift "../lib/", "."
5
-
6
- require "test/unit"
7
- require "sets/ts_read"
8
- require "sets/ts_write"