ffi-libarchive 0.4.2 → 1.0.3

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 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"