libarchive 0.1.1 → 0.1.2

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.
@@ -1,155 +1,155 @@
1
- #ifndef _LIBARCHIVE_INTERNAL_H_
2
- #define _LIBARCHIVE_INTERNAL_H_
3
-
4
- #ifdef HAVE_CONFIG_H
5
- #include "config.h"
6
- #endif
7
-
8
- #include <fcntl.h>
9
- #include <stdio.h>
10
- #include <stdlib.h>
11
- #include <string.h>
12
- #include <sys/types.h>
13
- #include <sys/stat.h>
14
- #include <errno.h>
15
-
16
- #ifndef _WIN32
17
- #include <unistd.h>
18
- #endif
19
-
20
- #ifdef _WIN32
21
- #ifdef stat
22
- #undef stat
23
- #endif
24
- #define stat _stat
25
- #endif // _WIN32
26
-
27
- #include <archive.h>
28
- #include <archive_entry.h>
29
-
30
- #include <ruby.h>
31
- #include <rubysig.h>
32
-
33
- #ifdef _WIN32
34
- #include "libarchive_win32.h"
35
- #endif
36
-
37
- #include "archive_write_open_rb_str.h"
38
- #include "archive_read_support_compression.h"
39
- #include "archive_read_support_format.h"
40
- #include "archive_write_set_compression.h"
41
-
42
- #ifdef LIBARCHIVE_EXPORTS
43
- #define DLLEXPORT __declspec(dllexport)
44
- #else
45
- #define DLLEXPORT
46
- #endif
47
-
48
- #define VERSION "0.1.1"
49
- #define BLOCK_SIZE 10240
50
- #define DATA_BUFFER_SIZE 65536
51
-
52
- #ifndef RSTRING_PTR
53
- #define RSTRING_PTR(s) (RSTRING(s)->ptr)
54
- #endif
55
- #ifndef RSTRING_LEN
56
- #define RSTRING_LEN(s) (RSTRING(s)->len)
57
- #endif
58
-
59
- #ifdef O_NONBLOCK
60
- #define LIBARCHIVE_O_NONBLOCK O_NONBLOCK
61
- #elif O_NDELAY
62
- #define LIBARCHIVE_O_NONBLOCK O_NDELAY
63
- #else
64
- #define LIBARCHIVE_O_NONBLOCK 0
65
- #endif
66
-
67
- #ifdef O_NOCTTY
68
- #define LIBARCHIVE_O_NOCTTY O_NOCTTY
69
- #else
70
- #define LIBARCHIVE_O_NOCTTY 0
71
- #endif
72
-
73
- #ifdef O_BINARY
74
- #define LIBARCHIVE_O_BINARY O_BINARY
75
- #else
76
- #define LIBARCHIVE_O_BINARY 0
77
- #endif
78
-
79
- #ifdef O_SYNC
80
- #define LIBARCHIVE_O_SYNC O_SYNC
81
- #else
82
- #define LIBARCHIVE_O_SYNC 0
83
- #endif
84
-
85
- #define O_FLAGS (O_RDONLY | O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_EXCL | O_TRUNC | \
86
- LIBARCHIVE_O_NONBLOCK | LIBARCHIVE_O_NOCTTY | LIBARCHIVE_O_BINARY | LIBARCHIVE_O_SYNC)
87
-
88
- #define EXTRACT_FLAGS_WITHOUT_ARCHIVE_EXTRACT_SPARSE \
89
- (ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME | \
90
- ARCHIVE_EXTRACT_NO_OVERWRITE | ARCHIVE_EXTRACT_UNLINK | ARCHIVE_EXTRACT_ACL | \
91
- ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_XATTR | ARCHIVE_EXTRACT_SECURE_SYMLINKS | \
92
- ARCHIVE_EXTRACT_SECURE_NODOTDOT | ARCHIVE_EXTRACT_NO_AUTODIR | \
93
- ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER)
94
-
95
- #ifdef ARCHIVE_EXTRACT_SPARSE
96
- #define EXTRACT_FLAGS (EXTRACT_FLAGS_WITHOUT_ARCHIVE_EXTRACT_SPARSE | ARCHIVE_EXTRACT_SPARSE)
97
- #else
98
- #define EXTRACT_FLAGS EXTRACT_FLAGS_WITHOUT_ARCHIVE_EXTRACT_SPARSE
99
- #endif
100
-
101
- struct rb_libarchive_archive_container {
102
- struct archive *ar;
103
- int eof;
104
- VALUE memory;
105
- };
106
-
107
- struct rb_libarchive_entry_container {
108
- struct archive_entry *ae;
109
- int must_close;
110
- };
111
-
112
- #define Check_Archive(p) do { \
113
- if ((p)->ar == NULL) { \
114
- rb_raise(rb_eArchiveError, "Invalid archive"); \
115
- } \
116
- } while(0)
117
-
118
- #define Check_Entry(p) do { \
119
- if ((p)->ae == NULL) { \
120
- rb_raise(rb_eArchiveError, "Invalid entry"); \
121
- } \
122
- } while(0)
123
-
124
- #define Check_Class(v, c) do { \
125
- if (!rb_obj_is_instance_of((v), (c))) { \
126
- rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", \
127
- rb_class2name(CLASS_OF(v)), rb_class2name(c)); \
128
- } \
129
- } while(0)
130
-
131
- #define Check_Class(v, c) do { \
132
- if (!rb_obj_is_instance_of((v), (c))) { \
133
- rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", \
134
- rb_class2name(CLASS_OF(v)), rb_class2name(c)); \
135
- } \
136
- } while(0)
137
-
138
- #define LONG2TIME(i) rb_funcall(rb_cTime, rb_intern("at"), 1, LONG2NUM(i))
139
- #define TIME2LONG(v) NUM2LONG(rb_funcall((v), rb_intern("tv_sec"), 0))
140
-
141
- #define archive_copy_error_string(a, b, n) do { \
142
- strncpy((b), archive_error_string(a), (n)); \
143
- (b)[((n) - 1)] = '\0'; \
144
- } while(0)
145
-
146
- VALUE rb_libarchive_archive_alloc(VALUE klass);
147
- VALUE rb_libarchive_entry_new(struct archive_entry *ae, int must_close);
148
- VALUE rb_libarchive_entry_close(VALUE self);
149
-
150
- void Init_libarchive_reader();
151
- void Init_libarchive_writer();
152
- void Init_libarchive_archive();
153
- void Init_libarchive_entry();
154
-
155
- #endif // _LIBARCHIVE_INTERNAL_H_
1
+ #ifndef _LIBARCHIVE_INTERNAL_H_
2
+ #define _LIBARCHIVE_INTERNAL_H_
3
+
4
+ #ifdef HAVE_CONFIG_H
5
+ #include "config.h"
6
+ #endif
7
+
8
+ #include <fcntl.h>
9
+ #include <stdio.h>
10
+ #include <stdlib.h>
11
+ #include <string.h>
12
+ #include <sys/types.h>
13
+ #include <sys/stat.h>
14
+ #include <errno.h>
15
+
16
+ #ifndef _WIN32
17
+ #include <unistd.h>
18
+ #endif
19
+
20
+ #ifdef _WIN32
21
+ #ifdef stat
22
+ #undef stat
23
+ #endif
24
+ #define stat _stat
25
+ #endif // _WIN32
26
+
27
+ #include <archive.h>
28
+ #include <archive_entry.h>
29
+
30
+ #include <ruby.h>
31
+ #include <rubysig.h>
32
+
33
+ #ifdef _WIN32
34
+ #include "libarchive_win32.h"
35
+ #endif
36
+
37
+ #include "archive_write_open_rb_str.h"
38
+ #include "archive_read_support_compression.h"
39
+ #include "archive_read_support_format.h"
40
+ #include "archive_write_set_compression.h"
41
+
42
+ #ifdef LIBARCHIVE_EXPORTS
43
+ #define DLLEXPORT __declspec(dllexport)
44
+ #else
45
+ #define DLLEXPORT
46
+ #endif
47
+
48
+ #define VERSION "0.1.2"
49
+ #define BLOCK_SIZE 10240
50
+ #define DATA_BUFFER_SIZE 65536
51
+
52
+ #ifndef RSTRING_PTR
53
+ #define RSTRING_PTR(s) (RSTRING(s)->ptr)
54
+ #endif
55
+ #ifndef RSTRING_LEN
56
+ #define RSTRING_LEN(s) (RSTRING(s)->len)
57
+ #endif
58
+
59
+ #ifdef O_NONBLOCK
60
+ #define LIBARCHIVE_O_NONBLOCK O_NONBLOCK
61
+ #elif O_NDELAY
62
+ #define LIBARCHIVE_O_NONBLOCK O_NDELAY
63
+ #else
64
+ #define LIBARCHIVE_O_NONBLOCK 0
65
+ #endif
66
+
67
+ #ifdef O_NOCTTY
68
+ #define LIBARCHIVE_O_NOCTTY O_NOCTTY
69
+ #else
70
+ #define LIBARCHIVE_O_NOCTTY 0
71
+ #endif
72
+
73
+ #ifdef O_BINARY
74
+ #define LIBARCHIVE_O_BINARY O_BINARY
75
+ #else
76
+ #define LIBARCHIVE_O_BINARY 0
77
+ #endif
78
+
79
+ #ifdef O_SYNC
80
+ #define LIBARCHIVE_O_SYNC O_SYNC
81
+ #else
82
+ #define LIBARCHIVE_O_SYNC 0
83
+ #endif
84
+
85
+ #define O_FLAGS (O_RDONLY | O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_EXCL | O_TRUNC | \
86
+ LIBARCHIVE_O_NONBLOCK | LIBARCHIVE_O_NOCTTY | LIBARCHIVE_O_BINARY | LIBARCHIVE_O_SYNC)
87
+
88
+ #define EXTRACT_FLAGS_WITHOUT_ARCHIVE_EXTRACT_SPARSE \
89
+ (ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME | \
90
+ ARCHIVE_EXTRACT_NO_OVERWRITE | ARCHIVE_EXTRACT_UNLINK | ARCHIVE_EXTRACT_ACL | \
91
+ ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_XATTR | ARCHIVE_EXTRACT_SECURE_SYMLINKS | \
92
+ ARCHIVE_EXTRACT_SECURE_NODOTDOT | ARCHIVE_EXTRACT_NO_AUTODIR | \
93
+ ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER)
94
+
95
+ #ifdef ARCHIVE_EXTRACT_SPARSE
96
+ #define EXTRACT_FLAGS (EXTRACT_FLAGS_WITHOUT_ARCHIVE_EXTRACT_SPARSE | ARCHIVE_EXTRACT_SPARSE)
97
+ #else
98
+ #define EXTRACT_FLAGS EXTRACT_FLAGS_WITHOUT_ARCHIVE_EXTRACT_SPARSE
99
+ #endif
100
+
101
+ struct rb_libarchive_archive_container {
102
+ struct archive *ar;
103
+ int eof;
104
+ VALUE memory;
105
+ };
106
+
107
+ struct rb_libarchive_entry_container {
108
+ struct archive_entry *ae;
109
+ int must_close;
110
+ };
111
+
112
+ #define Check_Archive(p) do { \
113
+ if ((p)->ar == NULL) { \
114
+ rb_raise(rb_eArchiveError, "Invalid archive"); \
115
+ } \
116
+ } while(0)
117
+
118
+ #define Check_Entry(p) do { \
119
+ if ((p)->ae == NULL) { \
120
+ rb_raise(rb_eArchiveError, "Invalid entry"); \
121
+ } \
122
+ } while(0)
123
+
124
+ #define Check_Class(v, c) do { \
125
+ if (!rb_obj_is_instance_of((v), (c))) { \
126
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", \
127
+ rb_class2name(CLASS_OF(v)), rb_class2name(c)); \
128
+ } \
129
+ } while(0)
130
+
131
+ #define Check_Class(v, c) do { \
132
+ if (!rb_obj_is_instance_of((v), (c))) { \
133
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", \
134
+ rb_class2name(CLASS_OF(v)), rb_class2name(c)); \
135
+ } \
136
+ } while(0)
137
+
138
+ #define LONG2TIME(i) rb_funcall(rb_cTime, rb_intern("at"), 1, LONG2NUM(i))
139
+ #define TIME2LONG(v) NUM2LONG(rb_funcall((v), rb_intern("tv_sec"), 0))
140
+
141
+ #define archive_copy_error_string(a, b, n) do { \
142
+ strncpy((b), archive_error_string(a), (n)); \
143
+ (b)[((n) - 1)] = '\0'; \
144
+ } while(0)
145
+
146
+ VALUE rb_libarchive_archive_alloc(VALUE klass);
147
+ VALUE rb_libarchive_entry_new(struct archive_entry *ae, int must_close);
148
+ VALUE rb_libarchive_entry_close(VALUE self);
149
+
150
+ void Init_libarchive_reader();
151
+ void Init_libarchive_writer();
152
+ void Init_libarchive_archive();
153
+ void Init_libarchive_entry();
154
+
155
+ #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
+ }