ffi-libarchive 0.4.4 → 1.0.4

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: ee3adc120723c76032310ce14cb7f3baa719e4652611b1970dd0a6abfcba52c9
4
- data.tar.gz: 90dcedb260ba9ec0747f34618d112e2118f10441e64cd11dad51ffdd084bdb62
3
+ metadata.gz: a8c73cb018db4e1227aa66b0f895999e2526c44b06c240a8be6457302d4d7e54
4
+ data.tar.gz: 86d0b798be119ea9884267662eb24103af23e7ed5a0ff407eb260b2e42a5216d
5
5
  SHA512:
6
- metadata.gz: c87837659aa48f7fae76486623e11ada02709d20ce550e48a95a64562a2184ec2607f5bbfc1518c4f8f0adc0a3ccce9ad3f2fc49246d5a9d603c40afeaa23c96
7
- data.tar.gz: 9a760bec0f9bfd48e55fc8a06743e1cef832999f2a345e738a264ea2bcd9e1bbf2deb3f98c0fb98a141c3dab29862dd031a82527905104f45eea13b31bc949b2
6
+ metadata.gz: 727b4d399308d3f18e23909698bf8f8a456f916c71ac2ae13fa7baf7915b707959f7be977a1192ab5707a2ded62b4a8e0edf6812510d90c580e778e81610ee4d
7
+ data.tar.gz: 87beb19eba6dcee8f0a15ec412175e246ecf13533a1adee1f2419b99abfc0b44eb22aecbfb382b88f23ffe19f463272a2261bd56211f801eb8a2acacc6c2d41d
@@ -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
@@ -1,4 +1,4 @@
1
- require "ffi"
1
+ require "ffi" unless defined?(FFI)
2
2
 
3
3
  module Archive
4
4
  module C
@@ -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.4".freeze
2
+ VERSION = "1.0.4".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.4
4
+ version: 1.0.4
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-11-05 00:00:00.000000000 Z
13
+ date: 2020-08-13 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.7
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.4
@@ -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,143 +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
- ["test/", "directory", 0755, nil ],
9
- ["test/b/", "directory", 0755, nil ],
10
- ["test/b/c/", "directory", 0755, nil ],
11
- ["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 ],
12
- ["test/b/c/d/", "directory", 0711, nil ],
13
- ["test/b/c/d/d.dat", "symbolic_link", 0777, "../c.dat" ],
14
- ["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 ],
15
- ["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 ]
16
- ].freeze
17
-
18
- def setup
19
- File.open("data/test.tar.gz", "rb") do |f|
20
- @archive_content = f.read
21
- end
22
- end
23
-
24
- def test_read_tar_gz_from_file
25
- Archive.read_open_filename("data/test.tar.gz") do |ar|
26
- verify_content(ar)
27
- end
28
- end
29
-
30
- def test_read_tar_gz_from_file_with_external_gunzip
31
- Archive.read_open_filename("data/test.tar.gz", "gunzip") do |ar|
32
- verify_content(ar)
33
- end
34
- end
35
-
36
- def test_read_tar_gz_from_memory
37
- Archive.read_open_memory(@archive_content) do |ar|
38
- verify_content(ar)
39
- end
40
- end
41
-
42
- def test_read_tar_gz_from_memory_with_external_gunzip
43
- Archive.read_open_memory(@archive_content, "gunzip") do |ar|
44
- verify_content(ar)
45
- end
46
- end
47
-
48
- def test_read_entry_bigger_than_internal_buffer
49
- alphabet = "abcdefghijklmnopqrstuvwxyz"
50
- entry_size = 1024 * 4 - 3
51
-
52
- srand
53
- content = ""
54
- 1.upto(entry_size) do |i|
55
- index = rand(alphabet.size)
56
- content += alphabet[index, 1]
57
- end
58
-
59
- Dir.mktmpdir do |dir|
60
- Archive.write_open_filename(dir + "/test.tar.gz",
61
- Archive::COMPRESSION_BZIP2, Archive::FORMAT_TAR) do |ar|
62
- ar.new_entry do |entry|
63
- entry.pathname = "chubby.dat"
64
- entry.mode = 0666
65
- entry.filetype = Archive::Entry::FILE
66
- entry.atime = Time.now.to_i
67
- entry.mtime = Time.now.to_i
68
- entry.size = entry_size
69
- ar.write_header(entry)
70
- ar.write_data(content)
71
- end
72
- end
73
-
74
- Archive.read_open_filename(dir + "/test.tar.gz") do |ar|
75
- ar.next_header
76
- data = ar.read_data
77
-
78
- assert_equal entry_size, data.size
79
- assert_equal content.size, data.size
80
- assert_equal content, data
81
- end
82
-
83
- Archive.read_open_filename(dir + "/test.tar.gz") do |ar|
84
- ar.next_header
85
- data = ""
86
- ar.read_data(128) { |chunk| data += chunk }
87
-
88
- assert_equal content, data
89
- end
90
- end
91
- end
92
-
93
- def test_extract_no_additional_flags
94
- Dir.mktmpdir do |dir|
95
- Archive.read_open_filename("data/test.tar.gz") do |ar|
96
- Dir.chdir(dir) do
97
- ar.each_entry do |e|
98
- ar.extract(e)
99
- assert_not_equal File.mtime(e.pathname), e.mtime
100
- end
101
- end
102
- end
103
- end
104
- end
105
-
106
- def test_extract_extract_time
107
- Dir.mktmpdir do |dir|
108
- Archive.read_open_filename("data/test.tar.gz") do |ar|
109
- Dir.chdir(dir) do
110
- ar.each_entry do |e|
111
- ar.extract(e, Archive::EXTRACT_TIME.to_i)
112
- next if e.directory? || e.symbolic_link?
113
- assert_equal File.mtime(e.pathname), e.mtime
114
- end
115
- end
116
- end
117
- end
118
- end
119
-
120
- private
121
-
122
- def verify_content(ar)
123
- content_spec_idx = 0
124
-
125
- while (entry = ar.next_header)
126
- expect_pathname, expect_type, expect_mode, expect_content = CONTENT_SPEC[content_spec_idx]
127
-
128
- assert_equal expect_pathname, entry.pathname
129
- assert_equal entry.send("#{expect_type}?"), true
130
- assert_equal expect_mode, (entry.mode & 07777)
131
-
132
- if entry.symbolic_link?
133
- assert_equal expect_content, entry.symlink
134
- elsif entry.file?
135
- content = ar.read_data(1024)
136
- assert_equal expect_content, content
137
- end
138
-
139
- content_spec_idx += 1
140
- end
141
- end
142
-
143
- end
@@ -1,122 +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
- ["test/", "directory", 0755, nil ],
9
- ["test/b/", "directory", 0755, nil ],
10
- ["test/b/c/", "directory", 0755, nil ],
11
- ["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 ],
12
- ["test/b/c/d/", "directory", 0711, nil ],
13
- ["test/b/c/d/d.dat", "symbolic_link", 0777, "../c.dat" ],
14
- ["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 ],
15
- ["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 ]
16
- ].freeze
17
-
18
- def test_end_to_end_write_read_tar_gz
19
- Dir.mktmpdir do |dir|
20
- Archive.write_open_filename(dir + "/test.tar.gz", :gzip, :tar) do |ar|
21
- write_content(ar)
22
- end
23
-
24
- verify_content(dir + "/test.tar.gz")
25
- end
26
- end
27
-
28
- def test_end_to_end_write_read_memory
29
- memory = ""
30
- Archive.write_open_memory(memory, Archive::COMPRESSION_GZIP, Archive::FORMAT_TAR) do |ar|
31
- write_content ar
32
- end
33
- verify_content_memory(memory)
34
- end
35
-
36
- def test_end_to_end_write_read_tar_gz_with_external_gzip
37
- Dir.mktmpdir do |dir|
38
- Archive.write_open_filename(dir + "/test.tar.gz", "gzip", :tar) do |ar|
39
- write_content(ar)
40
- end
41
-
42
- verify_content(dir + "/test.tar.gz")
43
- end
44
- end
45
-
46
- private
47
-
48
- def write_content(ar)
49
- content_spec_idx = 0
50
-
51
- while content_spec_idx < CONTENT_SPEC.size()
52
- entry_path, entry_type, entry_mode, entry_content = \
53
- CONTENT_SPEC[content_spec_idx]
54
-
55
- ar.new_entry do |entry|
56
- entry.pathname = entry_path
57
- entry.mode = entry_mode
58
- entry.filetype = eval "Archive::Entry::#{entry_type.upcase}" # rubocop:disable Security/Eval
59
- entry.size = entry_content.size if entry_content
60
- entry.symlink = entry_content if entry_type == "symbolic_link"
61
- entry.atime = Time.now.to_i
62
- entry.mtime = Time.now.to_i
63
- ar.write_header(entry)
64
-
65
- if entry_type == "file"
66
- ar.write_data(entry_content)
67
- end
68
- end
69
-
70
- content_spec_idx += 1
71
- end
72
- end
73
-
74
- def verify_content_memory(memory)
75
- Archive.read_open_memory(memory) do |ar|
76
- content_spec_idx = 0
77
-
78
- while (entry = ar.next_header)
79
- expect_pathname, expect_type, expect_mode, expect_content = \
80
- CONTENT_SPEC[content_spec_idx]
81
-
82
- assert_equal expect_pathname, entry.pathname
83
- assert_equal entry.send("#{expect_type}?"), true
84
- assert_equal expect_mode, (entry.mode & 07777)
85
-
86
- if entry.symbolic_link?
87
- assert_equal expect_content, entry.symlink
88
- elsif entry.file?
89
- content = ar.read_data(1024)
90
- assert_equal expect_content, content
91
- end
92
-
93
- content_spec_idx += 1
94
- end
95
- end
96
- end
97
-
98
- def verify_content(filename)
99
- Archive.read_open_filename(filename) do |ar|
100
- content_spec_idx = 0
101
-
102
- while (entry = ar.next_header)
103
- expect_pathname, expect_type, expect_mode, expect_content = \
104
- CONTENT_SPEC[content_spec_idx]
105
-
106
- assert_equal expect_pathname, entry.pathname
107
- assert_equal entry.send("#{expect_type}?"), true
108
- assert_equal expect_mode, (entry.mode & 07777)
109
-
110
- if entry.symbolic_link?
111
- assert_equal expect_content, entry.symlink
112
- elsif entry.file?
113
- content = ar.read_data(1024)
114
- assert_equal expect_content, content
115
- end
116
-
117
- content_spec_idx += 1
118
- end
119
- end
120
- end
121
-
122
- 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"