libarchive-ruby-fs 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,134 +1,135 @@
1
- #ifndef _LIBARCHIVE_INTERNAL_H_
2
- #define _LIBARCHIVE_INTERNAL_H_
3
-
4
- #include <fcntl.h>
5
- #include <stdio.h>
6
- #include <stdlib.h>
7
- #include <string.h>
8
- #include <sys/types.h>
9
- #include <sys/stat.h>
10
- #include <errno.h>
11
-
12
- #include <archive.h>
13
- #include <archive_entry.h>
14
-
15
- #include <ruby.h>
16
-
17
- #include "archive_write_open_rb_str.h"
18
- #include "archive_read_support_compression.h"
19
- #include "archive_read_support_format.h"
20
- #include "archive_write_set_compression.h"
21
-
22
- #ifdef LIBARCHIVE_EXPORTS
23
- #define DLLEXPORT __declspec(dllexport)
24
- #else
25
- #define DLLEXPORT
26
- #endif
27
-
28
- #define BLOCK_SIZE 10240
29
- #define DATA_BUFFER_SIZE 65536
30
-
31
- #ifndef RSTRING_PTR
32
- #define RSTRING_PTR(s) (RSTRING(s)->ptr)
33
- #endif
34
- #ifndef RSTRING_LEN
35
- #define RSTRING_LEN(s) (RSTRING(s)->len)
36
- #endif
37
-
38
- #ifdef O_NONBLOCK
39
- #define LIBARCHIVE_O_NONBLOCK O_NONBLOCK
40
- #elif O_NDELAY
41
- #define LIBARCHIVE_O_NONBLOCK O_NDELAY
42
- #else
43
- #define LIBARCHIVE_O_NONBLOCK 0
44
- #endif
45
-
46
- #ifdef O_NOCTTY
47
- #define LIBARCHIVE_O_NOCTTY O_NOCTTY
48
- #else
49
- #define LIBARCHIVE_O_NOCTTY 0
50
- #endif
51
-
52
- #ifdef O_BINARY
53
- #define LIBARCHIVE_O_BINARY O_BINARY
54
- #else
55
- #define LIBARCHIVE_O_BINARY 0
56
- #endif
57
-
58
- #ifdef O_SYNC
59
- #define LIBARCHIVE_O_SYNC O_SYNC
60
- #else
61
- #define LIBARCHIVE_O_SYNC 0
62
- #endif
63
-
64
- #define O_FLAGS (O_RDONLY | O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_EXCL | O_TRUNC | \
65
- LIBARCHIVE_O_NONBLOCK | LIBARCHIVE_O_NOCTTY | LIBARCHIVE_O_BINARY | LIBARCHIVE_O_SYNC)
66
-
67
- #define EXTRACT_FLAGS_WITHOUT_ARCHIVE_EXTRACT_SPARSE \
68
- (ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME | \
69
- ARCHIVE_EXTRACT_NO_OVERWRITE | ARCHIVE_EXTRACT_UNLINK | ARCHIVE_EXTRACT_ACL | \
70
- ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_XATTR | ARCHIVE_EXTRACT_SECURE_SYMLINKS | \
71
- ARCHIVE_EXTRACT_SECURE_NODOTDOT | ARCHIVE_EXTRACT_NO_AUTODIR | \
72
- ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER)
73
-
74
- #ifdef ARCHIVE_EXTRACT_SPARSE
75
- #define EXTRACT_FLAGS (EXTRACT_FLAGS_WITHOUT_ARCHIVE_EXTRACT_SPARSE | ARCHIVE_EXTRACT_SPARSE)
76
- #else
77
- #define EXTRACT_FLAGS EXTRACT_FLAGS_WITHOUT_ARCHIVE_EXTRACT_SPARSE
78
- #endif
79
-
80
- struct rb_libarchive_archive_container {
81
- struct archive *ar;
82
- int eof;
83
- VALUE memory;
84
- };
85
-
86
- struct rb_libarchive_entry_container {
87
- struct archive_entry *ae;
88
- int must_close;
89
- };
90
-
91
- #define Check_Archive(p) do { \
92
- if ((p)->ar == NULL) { \
93
- rb_raise(rb_eArchiveError, "Invalid archive"); \
94
- } \
95
- } while(0)
96
-
97
- #define Check_Entry(p) do { \
98
- if ((p)->ae == NULL) { \
99
- rb_raise(rb_eArchiveError, "Invalid entry"); \
100
- } \
101
- } while(0)
102
-
103
- #define Check_Class(v, c) do { \
104
- if (!rb_obj_is_instance_of((v), (c))) { \
105
- rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", \
106
- rb_class2name(CLASS_OF(v)), rb_class2name(c)); \
107
- } \
108
- } while(0)
109
-
110
- #define Check_Class(v, c) do { \
111
- if (!rb_obj_is_instance_of((v), (c))) { \
112
- rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", \
113
- rb_class2name(CLASS_OF(v)), rb_class2name(c)); \
114
- } \
115
- } while(0)
116
-
117
- #define LONG2TIME(i) rb_funcall(rb_cTime, rb_intern("at"), 1, LONG2NUM(i))
118
- #define TIME2LONG(v) NUM2LONG(rb_funcall((v), rb_intern("tv_sec"), 0))
119
-
120
- #define archive_copy_error_string(a, b, n) do { \
121
- strncpy((b), archive_error_string(a), (n)); \
122
- (b)[((n) - 1)] = '\0'; \
123
- } while(0)
124
-
125
- VALUE rb_libarchive_archive_alloc(VALUE klass);
126
- VALUE rb_libarchive_entry_new(struct archive_entry *ae, int must_close);
127
- VALUE rb_libarchive_entry_close(VALUE self);
128
-
129
- void Init_libarchive_reader();
130
- void Init_libarchive_writer();
131
- void Init_libarchive_archive();
132
- void Init_libarchive_entry();
133
-
134
- #endif // _LIBARCHIVE_INTERNAL_H_
1
+ #ifndef _LIBARCHIVE_INTERNAL_H_
2
+ #define _LIBARCHIVE_INTERNAL_H_
3
+
4
+ #include <fcntl.h>
5
+ #include <stdio.h>
6
+ #include <stdlib.h>
7
+ #include <string.h>
8
+ #include <sys/types.h>
9
+ #include <sys/stat.h>
10
+ #include <errno.h>
11
+
12
+ #include <archive.h>
13
+ #include <archive_entry.h>
14
+
15
+ #include <ruby.h>
16
+ #include <ruby/thread.h>
17
+
18
+ #include "archive_write_open_rb_str.h"
19
+ #include "archive_read_support_compression.h"
20
+ #include "archive_read_support_format.h"
21
+ #include "archive_write_set_compression.h"
22
+
23
+ #ifdef LIBARCHIVE_EXPORTS
24
+ #define DLLEXPORT __declspec(dllexport)
25
+ #else
26
+ #define DLLEXPORT
27
+ #endif
28
+
29
+ #define BLOCK_SIZE 10240
30
+ #define DATA_BUFFER_SIZE 65536
31
+
32
+ #ifndef RSTRING_PTR
33
+ #define RSTRING_PTR(s) (RSTRING(s)->ptr)
34
+ #endif
35
+ #ifndef RSTRING_LEN
36
+ #define RSTRING_LEN(s) (RSTRING(s)->len)
37
+ #endif
38
+
39
+ #ifdef O_NONBLOCK
40
+ #define LIBARCHIVE_O_NONBLOCK O_NONBLOCK
41
+ #elif O_NDELAY
42
+ #define LIBARCHIVE_O_NONBLOCK O_NDELAY
43
+ #else
44
+ #define LIBARCHIVE_O_NONBLOCK 0
45
+ #endif
46
+
47
+ #ifdef O_NOCTTY
48
+ #define LIBARCHIVE_O_NOCTTY O_NOCTTY
49
+ #else
50
+ #define LIBARCHIVE_O_NOCTTY 0
51
+ #endif
52
+
53
+ #ifdef O_BINARY
54
+ #define LIBARCHIVE_O_BINARY O_BINARY
55
+ #else
56
+ #define LIBARCHIVE_O_BINARY 0
57
+ #endif
58
+
59
+ #ifdef O_SYNC
60
+ #define LIBARCHIVE_O_SYNC O_SYNC
61
+ #else
62
+ #define LIBARCHIVE_O_SYNC 0
63
+ #endif
64
+
65
+ #define O_FLAGS (O_RDONLY | O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_EXCL | O_TRUNC | \
66
+ LIBARCHIVE_O_NONBLOCK | LIBARCHIVE_O_NOCTTY | LIBARCHIVE_O_BINARY | LIBARCHIVE_O_SYNC)
67
+
68
+ #define EXTRACT_FLAGS_WITHOUT_ARCHIVE_EXTRACT_SPARSE \
69
+ (ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME | \
70
+ ARCHIVE_EXTRACT_NO_OVERWRITE | ARCHIVE_EXTRACT_UNLINK | ARCHIVE_EXTRACT_ACL | \
71
+ ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_XATTR | ARCHIVE_EXTRACT_SECURE_SYMLINKS | \
72
+ ARCHIVE_EXTRACT_SECURE_NODOTDOT | ARCHIVE_EXTRACT_NO_AUTODIR | \
73
+ ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER)
74
+
75
+ #ifdef ARCHIVE_EXTRACT_SPARSE
76
+ #define EXTRACT_FLAGS (EXTRACT_FLAGS_WITHOUT_ARCHIVE_EXTRACT_SPARSE | ARCHIVE_EXTRACT_SPARSE)
77
+ #else
78
+ #define EXTRACT_FLAGS EXTRACT_FLAGS_WITHOUT_ARCHIVE_EXTRACT_SPARSE
79
+ #endif
80
+
81
+ struct rb_libarchive_archive_container {
82
+ struct archive *ar;
83
+ int eof;
84
+ VALUE memory;
85
+ };
86
+
87
+ struct rb_libarchive_entry_container {
88
+ struct archive_entry *ae;
89
+ int must_close;
90
+ };
91
+
92
+ #define Check_Archive(p) do { \
93
+ if ((p)->ar == NULL) { \
94
+ rb_raise(rb_eArchiveError, "Invalid archive"); \
95
+ } \
96
+ } while(0)
97
+
98
+ #define Check_Entry(p) do { \
99
+ if ((p)->ae == NULL) { \
100
+ rb_raise(rb_eArchiveError, "Invalid entry"); \
101
+ } \
102
+ } while(0)
103
+
104
+ #define Check_Class(v, c) do { \
105
+ if (!rb_obj_is_instance_of((v), (c))) { \
106
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", \
107
+ rb_class2name(CLASS_OF(v)), rb_class2name(c)); \
108
+ } \
109
+ } while(0)
110
+
111
+ #define Check_Class(v, c) do { \
112
+ if (!rb_obj_is_instance_of((v), (c))) { \
113
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", \
114
+ rb_class2name(CLASS_OF(v)), rb_class2name(c)); \
115
+ } \
116
+ } while(0)
117
+
118
+ #define LONG2TIME(i) rb_funcall(rb_cTime, rb_intern("at"), 1, LONG2NUM(i))
119
+ #define TIME2LONG(v) NUM2LONG(rb_funcall((v), rb_intern("tv_sec"), 0))
120
+
121
+ #define archive_copy_error_string(a, b, n) do { \
122
+ strncpy((b), archive_error_string(a), (n)); \
123
+ (b)[((n) - 1)] = '\0'; \
124
+ } while(0)
125
+
126
+ VALUE rb_libarchive_archive_alloc(VALUE klass);
127
+ VALUE rb_libarchive_entry_new(struct archive_entry *ae, int must_close);
128
+ VALUE rb_libarchive_entry_close(VALUE self);
129
+
130
+ void Init_libarchive_reader();
131
+ void Init_libarchive_writer();
132
+ void Init_libarchive_archive();
133
+ void Init_libarchive_entry();
134
+
135
+ #endif // _LIBARCHIVE_INTERNAL_H_
@@ -1,328 +1,328 @@
1
- #include "libarchive_internal.h"
2
-
3
- extern VALUE rb_mArchive;
4
- VALUE rb_cArchiveReader;
5
- extern VALUE rb_eArchiveError;
6
- extern VALUE rb_cArchiveEntry;
7
-
8
- static void rb_libarchive_reader_close0(struct rb_libarchive_archive_container *p) {
9
- archive_read_close(p->ar);
10
- archive_read_finish(p->ar);
11
- p->ar = NULL;
12
- }
13
-
14
- /* */
15
- static VALUE rb_libarchive_reader_close(VALUE self) {
16
- struct rb_libarchive_archive_container *p;
17
- Data_Get_Struct(self, struct rb_libarchive_archive_container, p);
18
- Check_Archive(p);
19
- rb_libarchive_reader_close0(p);
20
- return Qnil;
21
- }
22
-
23
- static VALUE rb_libarchive_reader_s_open0(int (*archive_open)(struct rb_libarchive_archive_container *, void *), void *arg, int compression, int format, const char *cmd) {
24
- VALUE reader;
25
- struct rb_libarchive_archive_container *p;
26
- int r;
27
- reader = rb_funcall(rb_cArchiveReader, rb_intern("new"), 0);
28
- Data_Get_Struct(reader, struct rb_libarchive_archive_container, p);
29
-
30
- if ((p->ar = archive_read_new()) == NULL) {
31
- rb_raise(rb_eArchiveError, "Open reader failed: %s", strerror(errno));
32
- }
33
-
34
- if (cmd != NULL) {
35
- r = archive_read_support_compression_program(p->ar, cmd);
36
- } else if (compression != -1) {
37
- r = archive_read_support_compression(p->ar, compression);
38
- } else {
39
- r = archive_read_support_compression_all(p->ar);
40
- }
41
-
42
- if (r != ARCHIVE_OK) {
43
- char error_string[BUFSIZ];
44
- archive_copy_error_string(p->ar, error_string, BUFSIZ);
45
- rb_libarchive_reader_close0(p);
46
- rb_raise(rb_eArchiveError, "Support compression failed: %s", error_string);
47
- }
48
-
49
- if (format != -1) {
50
- r = archive_read_support_format(p->ar, format);
51
- } else {
52
- r = archive_read_support_format_all(p->ar);
53
- }
54
-
55
- if (r != ARCHIVE_OK) {
56
- char error_string[BUFSIZ];
57
- archive_copy_error_string(p->ar, error_string, BUFSIZ);
58
- rb_libarchive_reader_close0(p);
59
- rb_raise(rb_eArchiveError, "Support format failed: %s", error_string);
60
- }
61
-
62
- if (archive_open(p, arg) != ARCHIVE_OK) {
63
- char error_string[BUFSIZ];
64
- archive_copy_error_string(p->ar, error_string, BUFSIZ);
65
- rb_libarchive_reader_close0(p);
66
- rb_raise(rb_eArchiveError, "Open reader failed: %s", error_string);
67
- }
68
-
69
- if (rb_block_given_p()) {
70
- VALUE retval;
71
- int status;
72
- retval = rb_protect(rb_yield, reader, &status);
73
- rb_libarchive_reader_close0(p);
74
-
75
- if (status != 0) {
76
- rb_jump_tag(status);
77
- }
78
-
79
- return retval;
80
- } else {
81
- return reader;
82
- }
83
- }
84
-
85
- static int rb_libarchive_reader_s_open_filename0(struct rb_libarchive_archive_container *p, void *arg) {
86
- const char *filename = (const char *) arg;
87
-
88
- if (filename != NULL) {
89
- struct stat s;
90
-
91
- if (stat(filename, &s) != 0) {
92
- archive_set_error(p->ar, -1, strerror(errno));
93
- return (ARCHIVE_FATAL);
94
- }
95
- }
96
-
97
- return archive_read_open_filename(p->ar, filename, BLOCK_SIZE);
98
- }
99
-
100
- /* */
101
- static VALUE rb_libarchive_reader_s_open_filename(int argc, VALUE *argv, VALUE self) {
102
- VALUE v_filename, v_compression, v_format;
103
- const char *filename = NULL;
104
- int compression = -1, format = -1;
105
- const char *cmd = NULL;
106
- rb_scan_args(argc, argv, "12", &v_filename, &v_compression, &v_format);
107
- Check_Type(v_filename, T_STRING);
108
- filename = RSTRING_PTR(v_filename);
109
-
110
- if (T_STRING == TYPE(v_compression)) {
111
- compression = -1;
112
- cmd = RSTRING_PTR(v_compression);
113
- } else if (!NIL_P(v_compression)) {
114
- compression = NUM2INT(v_compression);
115
- }
116
-
117
- if (!NIL_P(v_format)) {
118
- format = NUM2INT(v_format);
119
- }
120
-
121
- return rb_libarchive_reader_s_open0(rb_libarchive_reader_s_open_filename0, (void *) filename, compression, format, cmd);
122
- }
123
-
124
- static int rb_libarchive_reader_s_open_memory0(struct rb_libarchive_archive_container *p, void *arg) {
125
- VALUE v_buff = (VALUE) arg;
126
- return archive_read_open_memory(p->ar, RSTRING_PTR(v_buff), RSTRING_LEN(v_buff));
127
- }
128
-
129
- /* */
130
- static VALUE rb_libarchive_reader_s_open_memory(int argc, VALUE *argv, VALUE self) {
131
- VALUE v_memory, v_compression, v_format;
132
- int compression = -1, format = -1;
133
- const char *cmd = NULL;
134
- rb_scan_args(argc, argv, "12", &v_memory, &v_compression, &v_format);
135
- Check_Type(v_memory, T_STRING);
136
-
137
- if (T_STRING == TYPE(v_compression)) {
138
- compression = -1;
139
- cmd = RSTRING_PTR(v_compression);
140
- } else if (!NIL_P(v_compression)) {
141
- compression = NUM2INT(v_compression);
142
- }
143
-
144
- if (!NIL_P(v_format)) {
145
- format = NUM2INT(v_format);
146
- }
147
-
148
- return rb_libarchive_reader_s_open0(rb_libarchive_reader_s_open_memory0, (void *) v_memory, compression, format, cmd);
149
- }
150
-
151
- /* */
152
- static VALUE rb_libarchive_reader_next_header(VALUE self) {
153
- struct rb_libarchive_archive_container *p;
154
- struct archive_entry *ae;
155
- int r;
156
- Data_Get_Struct(self, struct rb_libarchive_archive_container, p);
157
- Check_Archive(p);
158
-
159
- if (p->eof) {
160
- return Qnil;
161
- }
162
-
163
- r = archive_read_next_header(p->ar, &ae);
164
-
165
- if (r == ARCHIVE_EOF) {
166
- p->eof = 1;
167
- return Qnil;
168
- } else if (r != ARCHIVE_OK) {
169
- rb_raise(rb_eArchiveError, "Fetch entry failed: %s", archive_error_string(p->ar));
170
- }
171
-
172
- return rb_libarchive_entry_new(ae, 0);
173
- }
174
-
175
- /* */
176
- static VALUE rb_libarchive_reader_header_position(VALUE self) {
177
- struct rb_libarchive_archive_container *p;
178
- Data_Get_Struct(self, struct rb_libarchive_archive_container, p);
179
- Check_Archive(p);
180
- return LONG2NUM((long) archive_read_header_position(p->ar));
181
- }
182
-
183
- /* */
184
- static VALUE rb_libarchive_reader_read_data(int argc, VALUE *argv, VALUE self) {
185
- VALUE v_size;
186
- struct rb_libarchive_archive_container *p;
187
- char *buff;
188
- size_t size = DATA_BUFFER_SIZE;
189
- ssize_t n;
190
- rb_scan_args(argc, argv, "01", &v_size);
191
-
192
- if (!NIL_P(v_size)) {
193
- size = NUM2INT(v_size);
194
- }
195
-
196
- Data_Get_Struct(self, struct rb_libarchive_archive_container, p);
197
- Check_Archive(p);
198
-
199
- if (p->eof) {
200
- return Qnil;
201
- }
202
-
203
- if (rb_block_given_p()) {
204
- ssize_t len = 0;
205
- int status = 0;
206
- buff = xmalloc(size);
207
-
208
- while ((n = archive_read_data(p->ar, buff, size)) > 0) {
209
- rb_protect(rb_yield, rb_str_new(buff, n), &status);
210
-
211
- if (status != 0) {
212
- break;
213
- }
214
-
215
- len += n;
216
- }
217
-
218
- xfree(buff);
219
-
220
- if (status != 0) {
221
- rb_jump_tag(status);
222
- }
223
-
224
- if (n < 0) {
225
- rb_raise(rb_eArchiveError, "Read data failed: %s", archive_error_string(p->ar));
226
- }
227
-
228
- return LONG2NUM(len);
229
- } else {
230
- VALUE retval = rb_str_new("", 0);
231
- buff = xmalloc(size);
232
-
233
- while ((n = archive_read_data(p->ar, buff, size)) > 0) {
234
- rb_str_cat(retval, buff, n);
235
- }
236
-
237
- xfree(buff);
238
-
239
- if (n < 0) {
240
- rb_raise(rb_eArchiveError, "Read data failed: %s", archive_error_string(p->ar));
241
- }
242
-
243
- return retval;
244
- }
245
- }
246
-
247
- /* */
248
- static VALUE rb_libarchive_reader_save_data(int argc, VALUE *argv, VALUE self) {
249
- VALUE v_filename, v_flags;
250
- struct rb_libarchive_archive_container *p;
251
- const char *filename;
252
- int flags, fd, r;
253
- rb_scan_args(argc, argv, "11", &v_filename, &v_flags);
254
- Check_Type(v_filename, T_STRING);
255
- filename = RSTRING_PTR(v_filename);
256
-
257
- if (!NIL_P(v_flags)) {
258
- flags = ((O_WRONLY | NUM2INT(v_flags)) & O_FLAGS);
259
- } else {
260
- flags = (O_WRONLY | O_CREAT | O_EXCL
261
- #ifdef O_BINARY
262
- | O_BINARY
263
- #endif
264
- );
265
- }
266
-
267
- Data_Get_Struct(self, struct rb_libarchive_archive_container, p);
268
- Check_Archive(p);
269
-
270
- if ((fd = open(filename, flags)) == -1) {
271
- rb_raise(rb_eArchiveError, "Save data failed: %s", strerror(errno));
272
- }
273
-
274
- r = archive_read_data_into_fd(p->ar, fd);
275
- close(fd);
276
-
277
- if (r != ARCHIVE_OK) {
278
- rb_raise(rb_eArchiveError, "Save data failed: %s", archive_error_string(p->ar));
279
- }
280
-
281
- return Qnil;
282
- }
283
-
284
- /* */
285
- static VALUE rb_libarchive_reader_extract(int argc, VALUE *argv, VALUE self) {
286
- VALUE v_entry, v_flags;
287
- struct rb_libarchive_archive_container *pa;
288
- struct rb_libarchive_entry_container *pae;
289
- int flags = 0;
290
- rb_scan_args(argc, argv, "11", &v_entry, &v_flags);
291
- Check_Class(v_entry, rb_cArchiveEntry);
292
-
293
- if (!NIL_P(v_flags)) {
294
- flags = (NUM2INT(v_flags) & EXTRACT_FLAGS);
295
- }
296
-
297
- Data_Get_Struct(self, struct rb_libarchive_archive_container, pa);
298
- Check_Archive(pa);
299
-
300
- if (pa->eof) {
301
- rb_raise(rb_eArchiveError, "Extract archive failed: It has already reached EOF");
302
- }
303
-
304
- Data_Get_Struct(v_entry, struct rb_libarchive_entry_container, pae);
305
- Check_Entry(pae);
306
-
307
- if (archive_read_extract(pa->ar, pae->ae, flags) != ARCHIVE_OK) {
308
- rb_raise(rb_eArchiveError, "Extract archive failed: %s", archive_error_string(pa->ar));
309
- }
310
-
311
- return Qnil;
312
- }
313
-
314
- void Init_libarchive_reader() {
315
- rb_cArchiveReader = rb_define_class_under(rb_mArchive, "Reader", rb_cObject);
316
- rb_define_alloc_func(rb_cArchiveReader, rb_libarchive_archive_alloc);
317
- rb_funcall(rb_cArchiveReader, rb_intern("private_class_method"), 1, ID2SYM(rb_intern("new")));
318
- rb_define_singleton_method(rb_cArchiveReader, "open_filename", rb_libarchive_reader_s_open_filename, -1);
319
- rb_define_module_function(rb_mArchive, "read_open_filename", rb_libarchive_reader_s_open_filename, -1);
320
- rb_define_singleton_method(rb_cArchiveReader, "open_memory", rb_libarchive_reader_s_open_memory, -1);
321
- rb_define_module_function(rb_mArchive, "read_open_memory", rb_libarchive_reader_s_open_memory, -1);
322
- rb_define_method(rb_cArchiveReader, "close", rb_libarchive_reader_close, 0);
323
- rb_define_method(rb_cArchiveReader, "next_header", rb_libarchive_reader_next_header, 0);
324
- rb_define_method(rb_cArchiveReader, "header_position", rb_libarchive_reader_header_position, 0);
325
- rb_define_method(rb_cArchiveReader, "read_data", rb_libarchive_reader_read_data, -1);
326
- rb_define_method(rb_cArchiveReader, "save_data", rb_libarchive_reader_save_data, -1);
327
- rb_define_method(rb_cArchiveReader, "extract", rb_libarchive_reader_extract, -1);
328
- }
1
+ #include "libarchive_internal.h"
2
+
3
+ extern VALUE rb_mArchive;
4
+ VALUE rb_cArchiveReader;
5
+ extern VALUE rb_eArchiveError;
6
+ extern VALUE rb_cArchiveEntry;
7
+
8
+ static void rb_libarchive_reader_close0(struct rb_libarchive_archive_container *p) {
9
+ archive_read_close(p->ar);
10
+ archive_read_finish(p->ar);
11
+ p->ar = NULL;
12
+ }
13
+
14
+ /* */
15
+ static VALUE rb_libarchive_reader_close(VALUE self) {
16
+ struct rb_libarchive_archive_container *p;
17
+ Data_Get_Struct(self, struct rb_libarchive_archive_container, p);
18
+ Check_Archive(p);
19
+ rb_libarchive_reader_close0(p);
20
+ return Qnil;
21
+ }
22
+
23
+ static VALUE rb_libarchive_reader_s_open0(int (*archive_open)(struct rb_libarchive_archive_container *, void *), void *arg, int compression, int format, const char *cmd) {
24
+ VALUE reader;
25
+ struct rb_libarchive_archive_container *p;
26
+ int r;
27
+ reader = rb_funcall(rb_cArchiveReader, rb_intern("new"), 0);
28
+ Data_Get_Struct(reader, struct rb_libarchive_archive_container, p);
29
+
30
+ if ((p->ar = archive_read_new()) == NULL) {
31
+ rb_raise(rb_eArchiveError, "Open reader failed: %s", strerror(errno));
32
+ }
33
+
34
+ if (cmd != NULL) {
35
+ r = archive_read_support_compression_program(p->ar, cmd);
36
+ } else if (compression != -1) {
37
+ r = archive_read_support_compression(p->ar, compression);
38
+ } else {
39
+ r = archive_read_support_compression_all(p->ar);
40
+ }
41
+
42
+ if (r != ARCHIVE_OK) {
43
+ char error_string[BUFSIZ];
44
+ archive_copy_error_string(p->ar, error_string, BUFSIZ);
45
+ rb_libarchive_reader_close0(p);
46
+ rb_raise(rb_eArchiveError, "Support compression failed: %s", error_string);
47
+ }
48
+
49
+ if (format != -1) {
50
+ r = archive_read_support_format(p->ar, format);
51
+ } else {
52
+ r = archive_read_support_format_all(p->ar);
53
+ }
54
+
55
+ if (r != ARCHIVE_OK) {
56
+ char error_string[BUFSIZ];
57
+ archive_copy_error_string(p->ar, error_string, BUFSIZ);
58
+ rb_libarchive_reader_close0(p);
59
+ rb_raise(rb_eArchiveError, "Support format failed: %s", error_string);
60
+ }
61
+
62
+ if (archive_open(p, arg) != ARCHIVE_OK) {
63
+ char error_string[BUFSIZ];
64
+ archive_copy_error_string(p->ar, error_string, BUFSIZ);
65
+ rb_libarchive_reader_close0(p);
66
+ rb_raise(rb_eArchiveError, "Open reader failed: %s", error_string);
67
+ }
68
+
69
+ if (rb_block_given_p()) {
70
+ VALUE retval;
71
+ int status;
72
+ retval = rb_protect(rb_yield, reader, &status);
73
+ rb_libarchive_reader_close0(p);
74
+
75
+ if (status != 0) {
76
+ rb_jump_tag(status);
77
+ }
78
+
79
+ return retval;
80
+ } else {
81
+ return reader;
82
+ }
83
+ }
84
+
85
+ static int rb_libarchive_reader_s_open_filename0(struct rb_libarchive_archive_container *p, void *arg) {
86
+ const char *filename = (const char *) arg;
87
+
88
+ if (filename != NULL) {
89
+ struct stat s;
90
+
91
+ if (stat(filename, &s) != 0) {
92
+ archive_set_error(p->ar, -1, strerror(errno));
93
+ return (ARCHIVE_FATAL);
94
+ }
95
+ }
96
+
97
+ return archive_read_open_filename(p->ar, filename, BLOCK_SIZE);
98
+ }
99
+
100
+ /* */
101
+ static VALUE rb_libarchive_reader_s_open_filename(int argc, VALUE *argv, VALUE self) {
102
+ VALUE v_filename, v_compression, v_format;
103
+ const char *filename = NULL;
104
+ int compression = -1, format = -1;
105
+ const char *cmd = NULL;
106
+ rb_scan_args(argc, argv, "12", &v_filename, &v_compression, &v_format);
107
+ Check_Type(v_filename, T_STRING);
108
+ filename = RSTRING_PTR(v_filename);
109
+
110
+ if (T_STRING == TYPE(v_compression)) {
111
+ compression = -1;
112
+ cmd = RSTRING_PTR(v_compression);
113
+ } else if (!NIL_P(v_compression)) {
114
+ compression = NUM2INT(v_compression);
115
+ }
116
+
117
+ if (!NIL_P(v_format)) {
118
+ format = NUM2INT(v_format);
119
+ }
120
+
121
+ return rb_libarchive_reader_s_open0(rb_libarchive_reader_s_open_filename0, (void *) filename, compression, format, cmd);
122
+ }
123
+
124
+ static int rb_libarchive_reader_s_open_memory0(struct rb_libarchive_archive_container *p, void *arg) {
125
+ VALUE v_buff = (VALUE) arg;
126
+ return archive_read_open_memory(p->ar, RSTRING_PTR(v_buff), RSTRING_LEN(v_buff));
127
+ }
128
+
129
+ /* */
130
+ static VALUE rb_libarchive_reader_s_open_memory(int argc, VALUE *argv, VALUE self) {
131
+ VALUE v_memory, v_compression, v_format;
132
+ int compression = -1, format = -1;
133
+ const char *cmd = NULL;
134
+ rb_scan_args(argc, argv, "12", &v_memory, &v_compression, &v_format);
135
+ Check_Type(v_memory, T_STRING);
136
+
137
+ if (T_STRING == TYPE(v_compression)) {
138
+ compression = -1;
139
+ cmd = RSTRING_PTR(v_compression);
140
+ } else if (!NIL_P(v_compression)) {
141
+ compression = NUM2INT(v_compression);
142
+ }
143
+
144
+ if (!NIL_P(v_format)) {
145
+ format = NUM2INT(v_format);
146
+ }
147
+
148
+ return rb_libarchive_reader_s_open0(rb_libarchive_reader_s_open_memory0, (void *) v_memory, compression, format, cmd);
149
+ }
150
+
151
+ /* */
152
+ static VALUE rb_libarchive_reader_next_header(VALUE self) {
153
+ struct rb_libarchive_archive_container *p;
154
+ struct archive_entry *ae;
155
+ int r;
156
+ Data_Get_Struct(self, struct rb_libarchive_archive_container, p);
157
+ Check_Archive(p);
158
+
159
+ if (p->eof) {
160
+ return Qnil;
161
+ }
162
+
163
+ r = archive_read_next_header(p->ar, &ae);
164
+
165
+ if (r == ARCHIVE_EOF) {
166
+ p->eof = 1;
167
+ return Qnil;
168
+ } else if (r != ARCHIVE_OK) {
169
+ rb_raise(rb_eArchiveError, "Fetch entry failed: %s", archive_error_string(p->ar));
170
+ }
171
+
172
+ return rb_libarchive_entry_new(ae, 0);
173
+ }
174
+
175
+ /* */
176
+ static VALUE rb_libarchive_reader_header_position(VALUE self) {
177
+ struct rb_libarchive_archive_container *p;
178
+ Data_Get_Struct(self, struct rb_libarchive_archive_container, p);
179
+ Check_Archive(p);
180
+ return LONG2NUM((long) archive_read_header_position(p->ar));
181
+ }
182
+
183
+ /* */
184
+ static VALUE rb_libarchive_reader_read_data(int argc, VALUE *argv, VALUE self) {
185
+ VALUE v_size;
186
+ struct rb_libarchive_archive_container *p;
187
+ char *buff;
188
+ size_t size = DATA_BUFFER_SIZE;
189
+ ssize_t n;
190
+ rb_scan_args(argc, argv, "01", &v_size);
191
+
192
+ if (!NIL_P(v_size)) {
193
+ size = NUM2INT(v_size);
194
+ }
195
+
196
+ Data_Get_Struct(self, struct rb_libarchive_archive_container, p);
197
+ Check_Archive(p);
198
+
199
+ if (p->eof) {
200
+ return Qnil;
201
+ }
202
+
203
+ if (rb_block_given_p()) {
204
+ ssize_t len = 0;
205
+ int status = 0;
206
+ buff = xmalloc(size);
207
+
208
+ while ((n = archive_read_data(p->ar, buff, size)) > 0) {
209
+ rb_protect(rb_yield, rb_str_new(buff, n), &status);
210
+
211
+ if (status != 0) {
212
+ break;
213
+ }
214
+
215
+ len += n;
216
+ }
217
+
218
+ xfree(buff);
219
+
220
+ if (status != 0) {
221
+ rb_jump_tag(status);
222
+ }
223
+
224
+ if (n < 0) {
225
+ rb_raise(rb_eArchiveError, "Read data failed: %s", archive_error_string(p->ar));
226
+ }
227
+
228
+ return LONG2NUM(len);
229
+ } else {
230
+ VALUE retval = rb_str_new("", 0);
231
+ buff = xmalloc(size);
232
+
233
+ while ((n = archive_read_data(p->ar, buff, size)) > 0) {
234
+ rb_str_cat(retval, buff, n);
235
+ }
236
+
237
+ xfree(buff);
238
+
239
+ if (n < 0) {
240
+ rb_raise(rb_eArchiveError, "Read data failed: %s", archive_error_string(p->ar));
241
+ }
242
+
243
+ return retval;
244
+ }
245
+ }
246
+
247
+ /* */
248
+ static VALUE rb_libarchive_reader_save_data(int argc, VALUE *argv, VALUE self) {
249
+ VALUE v_filename, v_flags;
250
+ struct rb_libarchive_archive_container *p;
251
+ const char *filename;
252
+ int flags, fd, r;
253
+ rb_scan_args(argc, argv, "11", &v_filename, &v_flags);
254
+ Check_Type(v_filename, T_STRING);
255
+ filename = RSTRING_PTR(v_filename);
256
+
257
+ if (!NIL_P(v_flags)) {
258
+ flags = ((O_WRONLY | NUM2INT(v_flags)) & O_FLAGS);
259
+ } else {
260
+ flags = (O_WRONLY | O_CREAT | O_EXCL
261
+ #ifdef O_BINARY
262
+ | O_BINARY
263
+ #endif
264
+ );
265
+ }
266
+
267
+ Data_Get_Struct(self, struct rb_libarchive_archive_container, p);
268
+ Check_Archive(p);
269
+
270
+ if ((fd = open(filename, flags)) == -1) {
271
+ rb_raise(rb_eArchiveError, "Save data failed: %s", strerror(errno));
272
+ }
273
+
274
+ r = archive_read_data_into_fd(p->ar, fd);
275
+ close(fd);
276
+
277
+ if (r != ARCHIVE_OK) {
278
+ rb_raise(rb_eArchiveError, "Save data failed: %s", archive_error_string(p->ar));
279
+ }
280
+
281
+ return Qnil;
282
+ }
283
+
284
+ /* */
285
+ static VALUE rb_libarchive_reader_extract(int argc, VALUE *argv, VALUE self) {
286
+ VALUE v_entry, v_flags;
287
+ struct rb_libarchive_archive_container *pa;
288
+ struct rb_libarchive_entry_container *pae;
289
+ int flags = 0;
290
+ rb_scan_args(argc, argv, "11", &v_entry, &v_flags);
291
+ Check_Class(v_entry, rb_cArchiveEntry);
292
+
293
+ if (!NIL_P(v_flags)) {
294
+ flags = (NUM2INT(v_flags) & EXTRACT_FLAGS);
295
+ }
296
+
297
+ Data_Get_Struct(self, struct rb_libarchive_archive_container, pa);
298
+ Check_Archive(pa);
299
+
300
+ if (pa->eof) {
301
+ rb_raise(rb_eArchiveError, "Extract archive failed: It has already reached EOF");
302
+ }
303
+
304
+ Data_Get_Struct(v_entry, struct rb_libarchive_entry_container, pae);
305
+ Check_Entry(pae);
306
+
307
+ if (archive_read_extract(pa->ar, pae->ae, flags) != ARCHIVE_OK) {
308
+ rb_raise(rb_eArchiveError, "Extract archive failed: %s", archive_error_string(pa->ar));
309
+ }
310
+
311
+ return Qnil;
312
+ }
313
+
314
+ void Init_libarchive_reader() {
315
+ rb_cArchiveReader = rb_define_class_under(rb_mArchive, "Reader", rb_cObject);
316
+ rb_define_alloc_func(rb_cArchiveReader, rb_libarchive_archive_alloc);
317
+ rb_funcall(rb_cArchiveReader, rb_intern("private_class_method"), 1, ID2SYM(rb_intern("new")));
318
+ rb_define_singleton_method(rb_cArchiveReader, "open_filename", rb_libarchive_reader_s_open_filename, -1);
319
+ rb_define_module_function(rb_mArchive, "read_open_filename", rb_libarchive_reader_s_open_filename, -1);
320
+ rb_define_singleton_method(rb_cArchiveReader, "open_memory", rb_libarchive_reader_s_open_memory, -1);
321
+ rb_define_module_function(rb_mArchive, "read_open_memory", rb_libarchive_reader_s_open_memory, -1);
322
+ rb_define_method(rb_cArchiveReader, "close", rb_libarchive_reader_close, 0);
323
+ rb_define_method(rb_cArchiveReader, "next_header", rb_libarchive_reader_next_header, 0);
324
+ rb_define_method(rb_cArchiveReader, "header_position", rb_libarchive_reader_header_position, 0);
325
+ rb_define_method(rb_cArchiveReader, "read_data", rb_libarchive_reader_read_data, -1);
326
+ rb_define_method(rb_cArchiveReader, "save_data", rb_libarchive_reader_save_data, -1);
327
+ rb_define_method(rb_cArchiveReader, "extract", rb_libarchive_reader_extract, -1);
328
+ }