zipruby 0.2.9 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of zipruby might be problematic. Click here for more details.

data/zipruby.c CHANGED
@@ -1,2201 +1,2201 @@
1
1
  /* rdoc source */
2
- #include <stdio.h>
3
- #include <stdlib.h>
4
- #include <string.h>
5
- #include <sys/types.h>
6
- #include <sys/stat.h>
7
-
8
- #ifdef _WIN32
9
- #include <windows.h>
10
- #include <io.h>
11
- #include <fcntl.h>
12
- #include <share.h>
13
- #endif
14
-
15
- #include "tmpfile.h"
16
- #include "ruby.h"
17
-
18
- #ifndef _WIN32
19
- #ifndef HAVE_MKSTEMP
20
- int _zip_mkstemp(char *);
21
- #define mkstemp _zip_mkstemp
22
- #endif
23
- #endif
24
-
25
- static int write_from_proc(VALUE proc, int fd);
26
- static VALUE proc_call(VALUE proc);
27
-
28
- char *zipruby_tmpnam(void *data, int len) {
29
- char *filnam;
30
-
31
- #ifdef _WIN32
32
- int fd;
33
- char tmpdirnam[_MAX_PATH];
34
- char tmpfilnam[_MAX_PATH];
35
- int namlen;
36
-
37
- memset(tmpdirnam, 0, _MAX_PATH);
38
-
39
- if (GetTempPathA(_MAX_PATH, tmpdirnam) == 0) {
40
- return NULL;
41
- }
42
-
43
- memset(tmpfilnam, 0, _MAX_PATH);
44
-
45
- if (GetTempFileNameA(tmpdirnam, "zrb", 0, tmpfilnam) == 0) {
46
- return NULL;
47
- }
48
-
49
- namlen = strlen(tmpfilnam) + 1;
50
-
51
- if ((filnam = calloc(namlen, sizeof(char))) == NULL) {
52
- return NULL;
53
- }
54
-
55
- if (strcpy_s(filnam, namlen, tmpfilnam) != 0) {
56
- free(filnam);
57
- return NULL;
58
- }
59
-
60
- if (data) {
61
- if ((_sopen_s(&fd, filnam, _O_WRONLY | _O_BINARY, _SH_DENYRD, _S_IWRITE)) != 0) {
62
- free(filnam);
63
- return NULL;
64
- }
65
-
66
- if (len < 0) {
67
- if (write_from_proc((VALUE) data, fd) == -1) {
68
- free(filnam);
69
- return NULL;
70
- }
71
- } else {
72
- if (_write(fd, data, len) == -1) {
73
- free(filnam);
74
- return NULL;
75
- }
76
- }
77
-
78
- if (_close(fd) == -1) {
79
- free(filnam);
80
- return NULL;
81
- }
82
- }
83
- #else
84
- int fd;
85
- #ifdef P_tmpdir
86
- int namlen = 16 + strlen(P_tmpdir);
87
- char *dirnam = P_tmpdir;
88
- #else
89
- int namlen = 20;
90
- char *dirnam = "/tmp";
91
- #endif
92
-
93
- if ((filnam = calloc(namlen, sizeof(char))) == NULL) {
94
- return NULL;
95
- }
96
-
97
- strcpy(filnam, dirnam);
98
- strcat(filnam, "/zipruby.XXXXXX");
99
-
100
- if ((fd = mkstemp(filnam)) == -1) {
101
- free(filnam);
102
- return NULL;
103
- }
104
-
105
- if (data) {
106
- if (len < 0) {
107
- if (write_from_proc((VALUE) data, fd) == -1) {
108
- free(filnam);
109
- return NULL;
110
- }
111
- } else {
112
- if (write(fd, data, len) == -1) {
113
- free(filnam);
114
- return NULL;
115
- }
116
- }
117
- }
118
-
119
- if (close(fd) == -1) {
120
- free(filnam);
121
- return NULL;
122
- }
123
- #endif
124
-
125
- return filnam;
126
- }
127
-
128
- void zipruby_rmtmp(const char *tmpfilnam) {
129
- struct stat st;
130
-
131
- if (!tmpfilnam) {
132
- return;
133
- }
134
-
135
- if (stat(tmpfilnam, &st) != 0) {
136
- return;
137
- }
138
-
139
- #ifdef _WIN32
140
- _unlink(tmpfilnam);
141
- #else
142
- unlink(tmpfilnam);
143
- #endif
144
- }
145
-
146
- static int write_from_proc(VALUE proc, int fd) {
147
- while (1) {
148
- VALUE src = rb_protect(proc_call, proc, NULL);
149
-
150
- if (TYPE(src) != T_STRING) {
151
- break;
152
- }
153
-
154
- if (RSTRING_LEN(src) < 1) {
155
- break;
156
- }
157
-
158
- #ifdef _WIN32
159
- if (_write(fd, RSTRING_PTR(src), RSTRING_LEN(src)) == -1) {
160
- return -1;
161
- }
162
- #else
163
- if (write(fd, RSTRING_PTR(src), RSTRING_LEN(src)) == -1) {
164
- return -1;
165
- }
166
- #endif
167
- }
168
-
169
- return 0;
170
- }
171
-
172
- static VALUE proc_call(VALUE proc) {
173
- return rb_funcall(proc, rb_intern("call"), 0);
174
- }
175
- #ifdef _WIN32
176
- __declspec(dllexport) void Init_zipruby(void);
177
- #endif
178
-
179
- #include "zipruby.h"
180
- #include "zipruby_zip.h"
181
- #include "zipruby_archive.h"
182
- #include "zipruby_file.h"
183
- #include "zipruby_stat.h"
184
- #include "zipruby_error.h"
185
-
186
- void Init_zipruby() {
187
- Init_zipruby_zip();
188
- Init_zipruby_archive();
189
- Init_zipruby_file();
190
- Init_zipruby_stat();
191
- Init_zipruby_error();
192
- }
193
- #include <errno.h>
194
-
195
- #include "zip.h"
196
- #include "zipruby.h"
197
- #include "zipruby_archive.h"
198
- #include "zipruby_zip_source_proc.h"
199
- #include "tmpfile.h"
200
- #include "ruby.h"
201
- #include "rubyio.h"
202
-
203
- static VALUE zipruby_archive_alloc(VALUE klass);
204
- static void zipruby_archive_mark(struct zipruby_archive *p);
205
- static void zipruby_archive_free(struct zipruby_archive *p);
206
- static VALUE zipruby_archive_s_open(int argc, VALUE *argv, VALUE self);
207
- static VALUE zipruby_archive_s_open_buffer(int argc, VALUE *argv, VALUE self);
208
- static VALUE zipruby_archive_s_decrypt(VALUE self, VALUE path, VALUE password);
209
- static VALUE zipruby_archive_s_encrypt(VALUE self, VALUE path, VALUE password);
210
- static VALUE zipruby_archive_close(VALUE self);
211
- static VALUE zipruby_archive_num_files(VALUE self);
212
- static VALUE zipruby_archive_get_name(int argc, VALUE *argv, VALUE self);
213
- static VALUE zipruby_archive_fopen(int argc, VALUE *argv, VALUE self);
214
- static VALUE zipruby_archive_get_stat(int argc, VALUE *argv, VALUE self);
215
- static VALUE zipruby_archive_add_buffer(VALUE self, VALUE name, VALUE source);
216
- static VALUE zipruby_archive_add_file(int argc, VALUE *argv, VALUE self);
217
- static VALUE zipruby_archive_add_io(VALUE self, VALUE name, VALUE io);
218
- static VALUE zipruby_archive_add_function(int argc, VALUE *argv, VALUE self);
219
- static VALUE zipruby_archive_replace_buffer(int argc, VALUE *argv, VALUE self);
220
- static VALUE zipruby_archive_replace_file(int argc, VALUE* argv, VALUE self);
221
- static VALUE zipruby_archive_replace_io(int argc, VALUE* argv, VALUE self);
222
- static VALUE zipruby_archive_replace_function(int argc, VALUE *argv, VALUE self);
223
- static VALUE zipruby_archive_add_or_replace_buffer(int argc, VALUE *argv, VALUE self);
224
- static VALUE zipruby_archive_add_or_replace_file(int argc, VALUE *argv, VALUE self);
225
- static VALUE zipruby_archive_add_or_replace_io(int argc, VALUE *argv, VALUE self);
226
- static VALUE zipruby_archive_add_or_replace_function(int argc, VALUE *argv, VALUE self);
227
- static VALUE zipruby_archive_update(int argc, VALUE *argv, VALUE self);
228
- static VALUE zipruby_archive_get_comment(int argc, VALUE *argv, VALUE self);
229
- static VALUE zipruby_archive_set_comment(VALUE self, VALUE comment);
230
- static VALUE zipruby_archive_locate_name(int argc, VALUE *argv, VALUE self);
231
- static VALUE zipruby_archive_get_fcomment(int argc, VALUE *argv, VALUE self);
232
- static VALUE zipruby_archive_set_fcomment(VALUE self, VALUE index, VALUE comment);
233
- static VALUE zipruby_archive_fdelete(VALUE self, VALUE index);
234
- static VALUE zipruby_archive_frename(VALUE self, VALUE index, VALUE name);
235
- static VALUE zipruby_archive_funchange(VALUE self, VALUE index);
236
- static VALUE zipruby_archive_funchange_all(VALUE self);
237
- static VALUE zipruby_archive_unchange(VALUE self);
238
- static VALUE zipruby_archive_revert(VALUE self);
239
- static VALUE zipruby_archive_each(VALUE self);
240
- static VALUE zipruby_archive_commit(VALUE self);
241
- static VALUE zipruby_archive_is_open(VALUE self);
242
- static VALUE zipruby_archive_decrypt(VALUE self, VALUE password);
243
- static VALUE zipruby_archive_encrypt(VALUE self, VALUE password);
244
- static VALUE zipruby_archive_read(VALUE self);
245
-
246
- extern VALUE Zip;
247
- VALUE Archive;
248
- extern VALUE File;
249
- extern VALUE Stat;
250
- extern VALUE Error;
251
-
252
- void Init_zipruby_archive() {
253
- Archive = rb_define_class_under(Zip, "Archive", rb_cObject);
254
- rb_define_alloc_func(Archive, zipruby_archive_alloc);
255
- rb_include_module(Archive, rb_mEnumerable);
256
- rb_define_singleton_method(Archive, "open", zipruby_archive_s_open, -1);
257
- rb_define_singleton_method(Archive, "open_buffer", zipruby_archive_s_open_buffer, -1);
258
- rb_define_singleton_method(Archive, "decrypt", zipruby_archive_s_decrypt, 2);
259
- rb_define_singleton_method(Archive, "encrypt", zipruby_archive_s_encrypt, 2);
260
- rb_define_method(Archive, "close", zipruby_archive_close, 0);
261
- rb_define_method(Archive, "num_files", zipruby_archive_num_files, 0);
262
- rb_define_method(Archive, "get_name", zipruby_archive_get_name, -1);
263
- rb_define_method(Archive, "fopen", zipruby_archive_fopen, -1);
264
- rb_define_method(Archive, "get_stat", zipruby_archive_get_stat, -1);
265
- rb_define_method(Archive, "add_buffer", zipruby_archive_add_buffer, 2);
266
- rb_define_method(Archive, "add_file", zipruby_archive_add_file, -1);
267
- rb_define_method(Archive, "add_io", zipruby_archive_add_io, 2);
268
- rb_define_method(Archive, "add", zipruby_archive_add_function, -1);
269
- rb_define_method(Archive, "replace_buffer", zipruby_archive_replace_buffer, -1);
270
- rb_define_method(Archive, "replace_file", zipruby_archive_replace_file, -1);
271
- rb_define_method(Archive, "replace_io", zipruby_archive_replace_io, -1);
272
- rb_define_method(Archive, "replace", zipruby_archive_replace_function, -1);
273
- rb_define_method(Archive, "add_or_replace_buffer", zipruby_archive_add_or_replace_buffer, -1);
274
- rb_define_method(Archive, "add_or_replace_file", zipruby_archive_add_or_replace_file, -1);
275
- rb_define_method(Archive, "add_or_replace_io", zipruby_archive_add_or_replace_io, -1);
276
- rb_define_method(Archive, "add_or_replace", zipruby_archive_add_or_replace_function, -1);
277
- rb_define_method(Archive, "update", zipruby_archive_update, -1);
278
- rb_define_method(Archive, "<<", zipruby_archive_add_io, 2);
279
- rb_define_method(Archive, "get_comment", zipruby_archive_get_comment, -1);
280
- rb_define_method(Archive, "comment", zipruby_archive_get_comment, -1);
281
- rb_define_method(Archive, "comment=", zipruby_archive_set_comment, 1);
282
- rb_define_method(Archive, "locate_name", zipruby_archive_locate_name, -1);
283
- rb_define_method(Archive, "get_fcomment", zipruby_archive_get_fcomment, -1);
284
- rb_define_method(Archive, "set_fcomment", zipruby_archive_set_fcomment, 2);
285
- rb_define_method(Archive, "fdelete", zipruby_archive_fdelete, 1);
286
- rb_define_method(Archive, "frename", zipruby_archive_frename, 2);
287
- rb_define_method(Archive, "funchange", zipruby_archive_funchange, 1);
288
- rb_define_method(Archive, "funchange_all", zipruby_archive_funchange_all, 0);
289
- rb_define_method(Archive, "unchange", zipruby_archive_unchange, 0);
290
- rb_define_method(Archive, "frevert", zipruby_archive_unchange, 1);
291
- rb_define_method(Archive, "revert", zipruby_archive_revert, 0);
292
- rb_define_method(Archive, "each", zipruby_archive_each, 0);
293
- rb_define_method(Archive, "commit", zipruby_archive_commit, 0);
294
- rb_define_method(Archive, "open?", zipruby_archive_is_open, 0);
295
- rb_define_method(Archive, "decrypt", zipruby_archive_decrypt, 1);
296
- rb_define_method(Archive, "encrypt", zipruby_archive_encrypt, 1);
297
- rb_define_method(Archive, "read", zipruby_archive_read, 0);
298
- }
299
-
300
- static VALUE zipruby_archive_alloc(VALUE klass) {
301
- struct zipruby_archive *p = ALLOC(struct zipruby_archive);
302
-
303
- p->archive = NULL;
304
- p->path = Qnil;
305
- p->flags = 0;
306
- p->tmpfilnam = NULL;
307
- p->buffer = Qnil;
308
-
309
- return Data_Wrap_Struct(klass, zipruby_archive_mark, zipruby_archive_free, p);
310
- }
311
-
312
- static void zipruby_archive_mark(struct zipruby_archive *p) {
313
- rb_gc_mark(p->path);
314
- rb_gc_mark(p->buffer);
315
- }
316
-
317
- static void zipruby_archive_free(struct zipruby_archive *p) {
318
- if (p->tmpfilnam) {
319
- zipruby_rmtmp(p->tmpfilnam);
320
- free(p->tmpfilnam);
321
- }
322
-
323
- xfree(p);
324
- }
325
-
326
- /* */
327
- static VALUE zipruby_archive_s_open(int argc, VALUE *argv, VALUE self) {
328
- VALUE path, flags;
329
- VALUE archive;
330
- struct zipruby_archive *p_archive;
331
- int i_flags = 0;
332
- int errorp;
333
-
334
- rb_scan_args(argc, argv, "11", &path, &flags);
335
- Check_Type(path, T_STRING);
336
-
337
- if (!NIL_P(flags)) {
338
- i_flags = NUM2INT(flags);
339
- }
340
-
341
- archive = rb_funcall(Archive, rb_intern("new"), 0);
342
- Data_Get_Struct(archive, struct zipruby_archive, p_archive);
343
-
344
- if ((p_archive->archive = zip_open(RSTRING_PTR(path), i_flags, &errorp)) == NULL) {
345
- char errstr[ERRSTR_BUFSIZE];
346
- zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
347
- rb_raise(Error, "Open archive failed - %s: %s", RSTRING_PTR(path), errstr);
348
- }
349
-
350
- p_archive->path = path;
351
- p_archive->flags = i_flags;
352
-
353
- if (rb_block_given_p()) {
354
- VALUE retval;
355
- int status;
356
-
357
- retval = rb_protect(rb_yield, archive, &status);
358
- zipruby_archive_close(archive);
359
-
360
- if (status != 0) {
361
- rb_jump_tag(status);
362
- }
363
-
364
- return retval;
365
- } else {
366
- return archive;
367
- }
368
- }
369
-
370
- /* */
371
- static VALUE zipruby_archive_s_open_buffer(int argc, VALUE *argv, VALUE self) {
372
- VALUE buffer, flags;
373
- VALUE archive;
374
- struct zipruby_archive *p_archive;
375
- void *data = NULL;
376
- int len = 0, i_flags = 0;
377
- int errorp;
378
-
379
- rb_scan_args(argc, argv, "02", &buffer, &flags);
380
-
381
- if (FIXNUM_P(buffer) && NIL_P(flags)) {
382
- flags = buffer;
383
- buffer = Qnil;
384
- }
385
-
386
- if (!NIL_P(flags)) {
387
- i_flags = NUM2INT(flags);
388
- }
389
-
390
- if (i_flags & ZIP_CREATE) {
391
- if (!NIL_P(buffer)) {
392
- Check_Type(buffer, T_STRING);
393
- }
394
-
395
- i_flags = (i_flags | ZIP_TRUNC);
396
- } else if (TYPE(buffer) == T_STRING) {
397
- data = RSTRING_PTR(buffer);
398
- len = RSTRING_LEN(buffer);
399
- } else if (rb_obj_is_instance_of(buffer, rb_cProc)) {
400
- data = (void *) buffer;
401
- len = -1;
402
- } else {
403
- rb_raise(rb_eTypeError, "wrong argument type %s (expected String or Proc)", rb_class2name(CLASS_OF(buffer)));
404
- }
405
-
406
- archive = rb_funcall(Archive, rb_intern("new"), 0);
407
- Data_Get_Struct(archive, struct zipruby_archive, p_archive);
408
-
409
- if ((p_archive->tmpfilnam = zipruby_tmpnam(data, len)) == NULL) {
410
- rb_raise(Error, "Open archive failed: Failed to create temporary file");
411
- }
412
-
413
- if ((p_archive->archive = zip_open(p_archive->tmpfilnam, i_flags, &errorp)) == NULL) {
414
- char errstr[ERRSTR_BUFSIZE];
415
- zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
416
- rb_raise(Error, "Open archive failed: %s", errstr);
417
- }
418
-
419
- p_archive->path = rb_str_new2(p_archive->tmpfilnam);
420
- p_archive->flags = i_flags;
421
- p_archive->buffer = buffer;
422
-
423
- if (rb_block_given_p()) {
424
- VALUE retval;
425
- int status;
426
-
427
- retval = rb_protect(rb_yield, archive, &status);
428
- zipruby_archive_close(archive);
429
-
430
- if (status != 0) {
431
- rb_jump_tag(status);
432
- }
433
-
434
- return retval;
435
- } else {
436
- return archive;
437
- }
438
- }
439
-
440
- /* */
441
- static VALUE zipruby_archive_s_decrypt(VALUE self, VALUE path, VALUE password) {
442
- int res;
443
- int errorp, wrongpwd;
444
- long pwdlen;
445
-
446
- Check_Type(path, T_STRING);
447
- Check_Type(password, T_STRING);
448
- pwdlen = RSTRING_LEN(password);
449
-
450
- if (pwdlen < 1) {
451
- rb_raise(Error, "Decrypt archive failed - %s: Password is empty", RSTRING_PTR(path));
452
- } else if (pwdlen > 0xff) {
453
- rb_raise(Error, "Decrypt archive failed - %s: Password is too long", RSTRING_PTR(path));
454
- }
455
-
456
- res = zip_decrypt(RSTRING_PTR(path), RSTRING_PTR(password), pwdlen, &errorp, &wrongpwd);
457
-
458
- if (res == -1) {
459
- if (wrongpwd) {
460
- rb_raise(Error, "Decrypt archive failed - %s: Wrong password", RSTRING_PTR(path));
461
- } else {
462
- char errstr[ERRSTR_BUFSIZE];
463
- zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
464
- rb_raise(Error, "Decrypt archive failed - %s: %s", RSTRING_PTR(path), errstr);
465
- }
466
- }
467
-
468
- return (res > 0) ? Qtrue : Qfalse;
469
- }
470
-
471
- /* */
472
- static VALUE zipruby_archive_s_encrypt(VALUE self, VALUE path, VALUE password) {
473
- int res;
474
- int errorp;
475
- long pwdlen;
476
-
477
- Check_Type(path, T_STRING);
478
- Check_Type(password, T_STRING);
479
- pwdlen = RSTRING_LEN(password);
480
-
481
- if (pwdlen < 1) {
482
- rb_raise(Error, "Encrypt archive failed - %s: Password is empty", RSTRING_PTR(path));
483
- } else if (pwdlen > 0xff) {
484
- rb_raise(Error, "Encrypt archive failed - %s: Password is too long", RSTRING_PTR(path));
485
- }
486
-
487
- res = zip_encrypt(RSTRING_PTR(path), RSTRING_PTR(password), pwdlen, &errorp);
488
-
489
- if (res == -1) {
490
- char errstr[ERRSTR_BUFSIZE];
491
- zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
492
- rb_raise(Error, "Encrypt archive failed - %s: %s", RSTRING_PTR(path), errstr);
493
- }
494
-
495
- return (res > 0) ? Qtrue : Qfalse;
496
- }
497
-
498
- /* */
499
- static VALUE zipruby_archive_close(VALUE self) {
500
- struct zipruby_archive *p_archive;
501
- int changed, survivors;
502
-
503
- if (!zipruby_archive_is_open(self)) {
504
- return Qfalse;
505
- }
506
-
507
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
508
- Check_Archive(p_archive);
509
-
510
- changed = _zip_changed(p_archive->archive, &survivors);
511
-
512
- if (zip_close(p_archive->archive) == -1) {
513
- zip_unchange_all(p_archive->archive);
514
- zip_unchange_archive(p_archive->archive);
515
- rb_raise(Error, "Close archive failed: %s", zip_strerror(p_archive->archive));
516
- }
517
-
518
- if (!NIL_P(p_archive->buffer) && changed) {
519
- rb_funcall(p_archive->buffer, rb_intern("replace"), 1, rb_funcall(self, rb_intern("read"), 0));
520
- }
521
-
522
- zipruby_rmtmp(p_archive->tmpfilnam);
523
- p_archive->archive = NULL;
524
- p_archive->flags = 0;
525
-
526
- return Qtrue;
527
- }
528
-
529
- /* */
530
- static VALUE zipruby_archive_num_files(VALUE self) {
531
- struct zipruby_archive *p_archive;
532
- int num_files;
533
-
534
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
535
- Check_Archive(p_archive);
536
- num_files = zip_get_num_files(p_archive->archive);
537
-
538
- return INT2NUM(num_files);
539
- }
540
-
541
- /* */
542
- static VALUE zipruby_archive_get_name(int argc, VALUE *argv, VALUE self) {
543
- VALUE index, flags;
544
- struct zipruby_archive *p_archive;
545
- int i_flags = 0;
546
- const char *name;
547
-
548
- rb_scan_args(argc, argv, "11", &index, &flags);
549
- Check_Type(index, T_FIXNUM);
550
-
551
- if (!NIL_P(flags)) {
552
- i_flags = NUM2INT(flags);
553
- }
554
-
555
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
556
- Check_Archive(p_archive);
557
-
558
- if ((name = zip_get_name(p_archive->archive, NUM2INT(index), i_flags)) == NULL) {
559
- rb_raise(Error, "Get name failed at %d: %s", index, zip_strerror(p_archive->archive));
560
- }
561
-
562
- return (name != NULL) ? rb_str_new2(name) : Qnil;
563
- }
564
-
565
- /* */
566
- static VALUE zipruby_archive_fopen(int argc, VALUE *argv, VALUE self) {
567
- VALUE index, flags, stat_flags, file;
568
-
569
- rb_scan_args(argc, argv, "12", &index, &flags, &stat_flags);
570
- file = rb_funcall(File, rb_intern("new"), 4, self, index, flags, stat_flags);
571
-
572
- if (rb_block_given_p()) {
573
- VALUE retval;
574
- int status;
575
-
576
- retval = rb_protect(rb_yield, file, &status);
577
- rb_funcall(file, rb_intern("close"), 0);
578
-
579
- if (status != 0) {
580
- rb_jump_tag(status);
581
- }
582
-
583
- return retval;
584
- } else {
585
- return file;
586
- }
587
- }
588
-
589
- /* */
590
- static VALUE zipruby_archive_get_stat(int argc, VALUE *argv, VALUE self) {
591
- VALUE index, flags;
592
-
593
- rb_scan_args(argc, argv, "11", &index, &flags);
594
-
595
- return rb_funcall(Stat, rb_intern("new"), 3, self, index, flags);
596
- }
597
-
598
- /* */
599
- static VALUE zipruby_archive_add_buffer(VALUE self, VALUE name, VALUE source) {
600
- struct zipruby_archive *p_archive;
601
- struct zip_source *zsource;
602
- char *data;
603
- off_t len;
604
-
605
- Check_Type(name, T_STRING);
606
- Check_Type(source, T_STRING);
607
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
608
- Check_Archive(p_archive);
609
-
610
- len = RSTRING_LEN(source);
611
-
612
- if ((data = malloc(len)) == NULL) {
613
- rb_raise(rb_eRuntimeError, "Add file failed: Cannot allocate memory");
614
- }
615
-
616
- memset(data, 0, len);
617
- memcpy(data, RSTRING_PTR(source), len);
618
-
619
- if ((zsource = zip_source_buffer(p_archive->archive, data, len, 1)) == NULL) {
620
- free(data);
621
- rb_raise(Error, "Add file failed - %s: %s", RSTRING_PTR(name), zip_strerror(p_archive->archive));
622
- }
623
-
624
- if (zip_add(p_archive->archive, RSTRING_PTR(name), zsource) == -1) {
625
- zip_source_free(zsource);
626
- zip_unchange_all(p_archive->archive);
627
- zip_unchange_archive(p_archive->archive);
628
- rb_raise(Error, "Add file failed - %s: %s", RSTRING_PTR(name), zip_strerror(p_archive->archive));
629
- }
630
-
631
- return Qnil;
632
- }
633
-
634
- /* */
635
- static VALUE zipruby_archive_replace_buffer(int argc, VALUE *argv, VALUE self) {
636
- struct zipruby_archive *p_archive;
637
- struct zip_source *zsource;
638
- VALUE index, source, flags;
639
- int i_index, i_flags = 0;
640
- char *data;
641
- off_t len;
642
-
643
- rb_scan_args(argc, argv, "21", &index, &source, &flags);
644
-
645
- if (TYPE(index) != T_STRING && !FIXNUM_P(index)) {
646
- rb_raise(rb_eTypeError, "wrong argument type %s (expected Fixnum or String)", rb_class2name(CLASS_OF(index)));
647
- }
648
-
649
- if (!NIL_P(flags)) {
650
- i_flags = NUM2INT(flags);
651
- }
652
-
653
- Check_Type(source, T_STRING);
654
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
655
- Check_Archive(p_archive);
656
-
657
- if (FIXNUM_P(index)) {
658
- i_index = NUM2INT(index);
659
- } else if ((i_index = zip_name_locate(p_archive->archive, RSTRING_PTR(index), i_flags)) == -1) {
660
- rb_raise(Error, "Replace file failed - %s: Archive does not contain a file", RSTRING_PTR(index));
661
- }
662
-
663
- len = RSTRING_LEN(source);
664
-
665
- if ((data = malloc(len)) == NULL) {
666
- rb_raise(rb_eRuntimeError, "Replace file failed: Cannot allocate memory");
667
- }
668
-
669
- memcpy(data, RSTRING_PTR(source), len);
670
-
671
- if ((zsource = zip_source_buffer(p_archive->archive, data, len, 1)) == NULL) {
672
- free(data);
673
- rb_raise(Error, "Replace file failed at %d: %s", i_index, zip_strerror(p_archive->archive));
674
- }
675
-
676
- if (zip_replace(p_archive->archive, i_index, zsource) == -1) {
677
- zip_source_free(zsource);
678
- zip_unchange_all(p_archive->archive);
679
- zip_unchange_archive(p_archive->archive);
680
- rb_raise(Error, "Replace file failed at %d: %s", i_index, zip_strerror(p_archive->archive));
681
- }
682
-
683
- return Qnil;
684
- }
685
-
686
- /* */
687
- static VALUE zipruby_archive_add_or_replace_buffer(int argc, VALUE *argv, VALUE self) {
688
- struct zipruby_archive *p_archive;
689
- VALUE name, source, flags;
690
- int index, i_flags = 0;
691
-
692
- rb_scan_args(argc, argv, "21", &name, &source, &flags);
693
-
694
- if (!NIL_P(flags)) {
695
- i_flags = NUM2INT(flags);
696
- }
697
-
698
- Check_Type(name, T_STRING);
699
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
700
- Check_Archive(p_archive);
701
-
702
- index = zip_name_locate(p_archive->archive, RSTRING_PTR(name), i_flags);
703
-
704
- if (index >= 0) {
705
- VALUE _args[] = { INT2NUM(index), source };
706
- return zipruby_archive_replace_buffer(2, _args, self);
707
- } else {
708
- return zipruby_archive_add_buffer(self, name, source);
709
- }
710
- }
711
-
712
- /* */
713
- static VALUE zipruby_archive_add_file(int argc, VALUE *argv, VALUE self) {
714
- VALUE name, fname;
715
- struct zipruby_archive *p_archive;
716
- struct zip_source *zsource;
717
-
718
- rb_scan_args(argc, argv, "11", &name, &fname);
719
-
720
- if (NIL_P(fname)) {
721
- fname = name;
722
- name = Qnil;
723
- }
724
-
725
- Check_Type(fname, T_STRING);
726
-
727
- if (NIL_P(name)) {
728
- name = rb_funcall(rb_cFile, rb_intern("basename"), 1, fname);
729
- }
730
-
731
- Check_Type(name, T_STRING);
732
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
733
- Check_Archive(p_archive);
734
-
735
- if ((zsource = zip_source_file(p_archive->archive, RSTRING_PTR(fname), 0, -1)) == NULL) {
736
- rb_raise(Error, "Add file failed - %s: %s", RSTRING_PTR(name), zip_strerror(p_archive->archive));
737
- }
738
-
739
- if (zip_add(p_archive->archive, RSTRING_PTR(name), zsource) == -1) {
740
- zip_source_free(zsource);
741
- zip_unchange_all(p_archive->archive);
742
- zip_unchange_archive(p_archive->archive);
743
- rb_raise(Error, "Add file failed - %s: %s", RSTRING_PTR(name), zip_strerror(p_archive->archive));
744
- }
745
-
746
- return Qnil;
747
- }
748
-
749
- /* */
750
- static VALUE zipruby_archive_replace_file(int argc, VALUE* argv, VALUE self) {
751
- struct zipruby_archive *p_archive;
752
- struct zip_source *zsource;
753
- VALUE index, fname, flags;
754
- int i_index, i_flags = 0;
755
-
756
- rb_scan_args(argc, argv, "21", &index, &fname, &flags);
757
-
758
- if (TYPE(index) != T_STRING && !FIXNUM_P(index)) {
759
- rb_raise(rb_eTypeError, "wrong argument type %s (expected Fixnum or String)", rb_class2name(CLASS_OF(index)));
760
- }
761
-
762
- if (!NIL_P(flags)) {
763
- i_flags = NUM2INT(flags);
764
- }
765
-
766
- Check_Type(fname, T_STRING);
767
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
768
- Check_Archive(p_archive);
769
-
770
- if (FIXNUM_P(index)) {
771
- i_index = NUM2INT(index);
772
- } else if ((i_index = zip_name_locate(p_archive->archive, RSTRING_PTR(index), i_flags)) == -1) {
773
- rb_raise(Error, "Replace file failed - %s: Archive does not contain a file", RSTRING_PTR(index));
774
- }
775
-
776
- if ((zsource = zip_source_file(p_archive->archive, RSTRING_PTR(fname), 0, -1)) == NULL) {
777
- rb_raise(Error, "Replace file failed at %d: %s", i_index, zip_strerror(p_archive->archive));
778
- }
779
-
780
- if (zip_replace(p_archive->archive, i_index, zsource) == -1) {
781
- zip_source_free(zsource);
782
- zip_unchange_all(p_archive->archive);
783
- zip_unchange_archive(p_archive->archive);
784
- rb_raise(Error, "Replace file failed at %d: %s", i_index, zip_strerror(p_archive->archive));
785
- }
786
-
787
- return Qnil;
788
- }
789
-
790
- /* */
791
- static VALUE zipruby_archive_add_or_replace_file(int argc, VALUE *argv, VALUE self) {
792
- VALUE name, fname, flags;
793
- struct zipruby_archive *p_archive;
794
- int index, i_flags = 0;
795
-
796
- rb_scan_args(argc, argv, "12", &name, &fname, &flags);
797
-
798
- if (NIL_P(flags) && FIXNUM_P(fname)) {
799
- flags = fname;
800
- fname = Qnil;
801
- }
802
-
803
- if (NIL_P(fname)) {
804
- fname = name;
805
- name = Qnil;
806
- }
807
-
808
- Check_Type(fname, T_STRING);
809
-
810
- if (NIL_P(name)) {
811
- name = rb_funcall(rb_cFile, rb_intern("basename"), 1, fname);
812
- }
813
-
814
- if (!NIL_P(flags)) {
815
- i_flags = NUM2INT(flags);
816
- }
817
-
818
- Check_Type(name, T_STRING);
819
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
820
- Check_Archive(p_archive);
821
-
822
- index = zip_name_locate(p_archive->archive, RSTRING_PTR(name), i_flags);
823
-
824
- if (index >= 0) {
825
- VALUE _args[] = { INT2NUM(index), fname };
826
- return zipruby_archive_replace_file(2, _args, self);
827
- } else {
828
- VALUE _args[] = { name, fname };
829
- return zipruby_archive_add_file(2, _args, self);
830
- }
831
- }
832
-
833
- /* */
834
- static VALUE zipruby_archive_add_io(VALUE self, VALUE name, VALUE io) {
835
- VALUE source;
836
-
837
- Check_IO(io);
838
- source = rb_funcall(io, rb_intern("read"), 0);
839
-
840
- return zipruby_archive_add_buffer(self, name, source);
841
- }
842
-
843
- /* */
844
- static VALUE zipruby_archive_replace_io(int argc, VALUE *argv, VALUE self) {
845
- VALUE source, io, index, flags;
846
- VALUE _args[3];
847
-
848
- rb_scan_args(argc, argv, "21", &index, &io, &flags);
849
- Check_IO(io);
850
- source = rb_funcall(io, rb_intern("read"), 0);
851
-
852
- _args[0] = index;
853
- _args[1] = source;
854
- _args[2] = flags;
855
- return zipruby_archive_replace_file(2, _args, self);
856
- }
857
-
858
- /* */
859
- static VALUE zipruby_archive_add_or_replace_io(int argc, VALUE *argv, VALUE self) {
860
- VALUE name, io, flags;
861
- struct zipruby_archive *p_archive;
862
- int index, i_flags = 0;
863
-
864
- rb_scan_args(argc, argv, "21", &name, &io, &flags);
865
- Check_IO(io);
866
-
867
- if (!NIL_P(flags)) {
868
- i_flags = NUM2INT(flags);
869
- }
870
-
871
- Check_Type(name, T_STRING);
872
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
873
- Check_Archive(p_archive);
874
-
875
- index = zip_name_locate(p_archive->archive, RSTRING_PTR(name), i_flags);
876
-
877
- if (index >= 0) {
878
- VALUE _args[] = {INT2NUM(index), io, flags};
879
- return zipruby_archive_replace_io(2, _args, self);
880
- } else {
881
- return zipruby_archive_add_io(self ,name, io);
882
- }
883
- }
884
-
885
- /* */
886
- static VALUE zipruby_archive_add_function(int argc, VALUE *argv, VALUE self) {
887
- VALUE name, mtime;
888
- struct zipruby_archive *p_archive;
889
- struct zip_source *zsource;
890
- struct read_proc *z;
891
-
892
- rb_scan_args(argc, argv, "11", &name, &mtime);
893
- rb_need_block();
894
- Check_Type(name, T_STRING);
895
-
896
- if (NIL_P(mtime)) {
897
- mtime = rb_funcall(rb_cTime, rb_intern("now"), 0);
898
- } else if (!rb_obj_is_instance_of(mtime, rb_cTime)) {
899
- rb_raise(rb_eTypeError, "wrong argument type %s (expected Time)", rb_class2name(CLASS_OF(mtime)));
900
- }
901
-
902
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
903
- Check_Archive(p_archive);
904
-
905
- if ((z = malloc(sizeof(struct read_proc))) == NULL) {
906
- zip_unchange_all(p_archive->archive);
907
- zip_unchange_archive(p_archive->archive);
908
- rb_raise(rb_eRuntimeError, "Add failed - %s: Cannot allocate memory", RSTRING_PTR(name));
909
- }
910
-
911
- z->proc = rb_block_proc();
912
- z->mtime = mtime;
913
-
914
- if ((zsource = zip_source_proc(p_archive->archive, z)) == NULL) {
915
- free(z);
916
- rb_raise(Error, "Add failed - %s: %s", RSTRING_PTR(name), zip_strerror(p_archive->archive));
917
- }
918
-
919
- if (zip_add(p_archive->archive, RSTRING_PTR(name), zsource) == -1) {
920
- zip_source_free(zsource);
921
- zip_unchange_all(p_archive->archive);
922
- zip_unchange_archive(p_archive->archive);
923
- rb_raise(Error, "Add file failed - %s: %s", RSTRING_PTR(name), zip_strerror(p_archive->archive));
924
- }
925
-
926
- return Qnil;
927
- }
928
-
929
- /* */
930
- static VALUE zipruby_archive_replace_function(int argc, VALUE *argv, VALUE self) {
931
- VALUE index, mtime;
932
- struct zipruby_archive *p_archive;
933
- struct zip_source *zsource;
934
- struct read_proc *z;
935
-
936
- rb_scan_args(argc, argv, "11", &index, &mtime);
937
- rb_need_block();
938
- Check_Type(index, T_FIXNUM);
939
-
940
- if (NIL_P(mtime)) {
941
- mtime = rb_funcall(rb_cTime, rb_intern("now"), 0);
942
- } else if (!rb_obj_is_instance_of(mtime, rb_cTime)) {
943
- rb_raise(rb_eTypeError, "wrong argument type %s (expected Time)", rb_class2name(CLASS_OF(mtime)));
944
- }
945
-
946
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
947
- Check_Archive(p_archive);
948
-
949
- if ((z = malloc(sizeof(struct read_proc))) == NULL) {
950
- zip_unchange_all(p_archive->archive);
951
- zip_unchange_archive(p_archive->archive);
952
- rb_raise(rb_eRuntimeError, "Replace failed at %d: Cannot allocate memory", NUM2INT(index));
953
- }
954
-
955
- z->proc = rb_block_proc();
956
- z->mtime = mtime;
957
-
958
- if ((zsource = zip_source_proc(p_archive->archive, z)) == NULL) {
959
- free(z);
960
- rb_raise(Error, "Replace failed at %d: %s", NUM2INT(index), zip_strerror(p_archive->archive));
961
- }
962
-
963
- if (zip_replace(p_archive->archive, NUM2INT(index), zsource) == -1) {
964
- zip_source_free(zsource);
965
- zip_unchange_all(p_archive->archive);
966
- zip_unchange_archive(p_archive->archive);
967
- rb_raise(Error, "Replace failed at %d: %s", NUM2INT(index), zip_strerror(p_archive->archive));
968
- }
969
-
970
- return Qnil;
971
- }
972
-
973
- /* */
974
- static VALUE zipruby_archive_add_or_replace_function(int argc, VALUE *argv, VALUE self) {
975
- VALUE name, mtime, flags;
976
- struct zipruby_archive *p_archive;
977
- int index, i_flags = 0;
978
-
979
- rb_scan_args(argc, argv, "12", &name, &mtime, &flags);
980
-
981
- if (NIL_P(flags) && FIXNUM_P(mtime)) {
982
- flags = mtime;
983
- mtime = Qnil;
984
- }
985
-
986
- if (!NIL_P(flags)) {
987
- i_flags = NUM2INT(flags);
988
- }
989
-
990
- Check_Type(name, T_STRING);
991
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
992
- Check_Archive(p_archive);
993
-
994
- index = zip_name_locate(p_archive->archive, RSTRING_PTR(name), i_flags);
995
-
996
- if (index >= 0) {
997
- VALUE _args[] = { INT2NUM(index), mtime };
998
- return zipruby_archive_replace_function(2, _args, self);
999
- } else {
1000
- VALUE _args[] = { name, mtime };
1001
- return zipruby_archive_add_function(2, _args, self);
1002
- }
1003
- }
1004
-
1005
- /* */
1006
- static VALUE zipruby_archive_update(int argc, VALUE *argv, VALUE self) {
1007
- struct zipruby_archive *p_archive, *p_srcarchive;
1008
- VALUE srcarchive, flags;
1009
- int i, num_files, i_flags = 0;
1010
-
1011
- rb_scan_args(argc, argv, "11", &srcarchive, &flags);
1012
-
1013
- if (!rb_obj_is_instance_of(srcarchive, Archive)) {
1014
- rb_raise(rb_eTypeError, "wrong argument type %s (expected Zip::Archive)", rb_class2name(CLASS_OF(srcarchive)));
1015
- }
1016
-
1017
- if (!NIL_P(flags)) {
1018
- i_flags = NUM2INT(flags);
1019
- }
1020
-
1021
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
1022
- Check_Archive(p_archive);
1023
- Data_Get_Struct(srcarchive, struct zipruby_archive, p_srcarchive);
1024
- Check_Archive(p_srcarchive);
1025
-
1026
- num_files = zip_get_num_files(p_srcarchive->archive);
1027
-
1028
- for (i = 0; i < num_files; i++) {
1029
- struct zip_source *zsource;
1030
- struct zip_file *fzip;
1031
- struct zip_stat sb;
1032
- char *buf;
1033
- const char *name;
1034
- int index, error;
1035
-
1036
- zip_stat_init(&sb);
1037
-
1038
- if (zip_stat_index(p_srcarchive->archive, i, 0, &sb)) {
1039
- zip_unchange_all(p_archive->archive);
1040
- zip_unchange_archive(p_archive->archive);
1041
- rb_raise(Error, "Update archive failed: %s", zip_strerror(p_srcarchive->archive));
1042
- }
1043
-
1044
- if ((buf = malloc(sb.size)) == NULL) {
1045
- zip_unchange_all(p_archive->archive);
1046
- zip_unchange_archive(p_archive->archive);
1047
- rb_raise(rb_eRuntimeError, "Update archive failed: Cannot allocate memory");
1048
- }
1049
-
1050
- fzip = zip_fopen_index(p_srcarchive->archive, i, 0);
1051
-
1052
- if (fzip == NULL) {
1053
- free(buf);
1054
- zip_unchange_all(p_archive->archive);
1055
- zip_unchange_archive(p_archive->archive);
1056
- rb_raise(Error, "Update archive failed: %s", zip_strerror(p_srcarchive->archive));
1057
- }
1058
-
1059
- if (zip_fread(fzip, buf, sb.size) == -1) {
1060
- free(buf);
1061
- zip_fclose(fzip);
1062
- zip_unchange_all(p_archive->archive);
1063
- zip_unchange_archive(p_archive->archive);
1064
- rb_raise(Error, "Update archive failed: %s", zip_file_strerror(fzip));
1065
- }
1066
-
1067
- if ((error = zip_fclose(fzip)) != 0) {
1068
- char errstr[ERRSTR_BUFSIZE];
1069
- free(buf);
1070
- zip_unchange_all(p_archive->archive);
1071
- zip_unchange_archive(p_archive->archive);
1072
- zip_error_to_str(errstr, ERRSTR_BUFSIZE, error, errno);
1073
- rb_raise(Error, "Update archive failed: %s", errstr);
1074
- }
1075
-
1076
- if ((zsource = zip_source_buffer(p_archive->archive, buf, sb.size, 1)) == NULL) {
1077
- free(buf);
1078
- zip_unchange_all(p_archive->archive);
1079
- zip_unchange_archive(p_archive->archive);
1080
- rb_raise(Error, "Update archive failed: %s", zip_strerror(p_archive->archive));
1081
- }
1082
-
1083
- if ((name = zip_get_name(p_srcarchive->archive, i, 0)) == NULL) {
1084
- zip_source_free(zsource);
1085
- zip_unchange_all(p_archive->archive);
1086
- zip_unchange_archive(p_archive->archive);
1087
- rb_raise(Error, "Update archive failed: %s", zip_strerror(p_srcarchive->archive));
1088
- }
1089
-
1090
- index = zip_name_locate(p_archive->archive, name, i_flags);
1091
-
1092
- if (index >= 0) {
1093
- if (zip_replace(p_archive->archive, i, zsource) == -1) {
1094
- zip_source_free(zsource);
1095
- zip_unchange_all(p_archive->archive);
1096
- zip_unchange_archive(p_archive->archive);
1097
- rb_raise(Error, "Update archive failed: %s", zip_strerror(p_archive->archive));
1098
- }
1099
- } else {
1100
- if (zip_add(p_archive->archive, name, zsource) == -1) {
1101
- zip_source_free(zsource);
1102
- zip_unchange_all(p_archive->archive);
1103
- zip_unchange_archive(p_archive->archive);
1104
- rb_raise(Error, "Update archive failed: %s", zip_strerror(p_archive->archive));
1105
- }
1106
- }
1107
- }
1108
-
1109
- return Qnil;
1110
- }
1111
-
1112
- /* */
1113
- static VALUE zipruby_archive_get_comment(int argc, VALUE *argv, VALUE self) {
1114
- VALUE flags;
1115
- struct zipruby_archive *p_archive;
1116
- const char *comment;
1117
- int lenp, i_flags = 0;
1118
-
1119
- rb_scan_args(argc, argv, "01", &flags);
1120
-
1121
- if (!NIL_P(flags)) {
1122
- i_flags = NUM2INT(flags);
1123
- }
1124
-
1125
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
1126
- Check_Archive(p_archive);
1127
-
1128
- // XXX: How is the error checked?
1129
- comment = zip_get_archive_comment(p_archive->archive, &lenp, i_flags);
1130
-
1131
- return comment ? rb_str_new(comment, lenp) : Qnil;
1132
- }
1133
-
1134
- /* */
1135
- static VALUE zipruby_archive_set_comment(VALUE self, VALUE comment) {
1136
- struct zipruby_archive *p_archive;
1137
- const char *s_comment = NULL;
1138
- int len = 0;
1139
-
1140
- if (!NIL_P(comment)) {
1141
- Check_Type(comment, T_STRING);
1142
- s_comment = RSTRING_PTR(comment);
1143
- len = RSTRING_LEN(comment);
1144
- }
1145
-
1146
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
1147
- Check_Archive(p_archive);
1148
-
1149
- if (zip_set_archive_comment(p_archive->archive, s_comment, len) == -1) {
1150
- zip_unchange_all(p_archive->archive);
1151
- zip_unchange_archive(p_archive->archive);
1152
- rb_raise(Error, "Comment archived failed: %s", zip_strerror(p_archive->archive));
1153
- }
1154
-
1155
- return Qnil;
1156
- }
1157
-
1158
- /* */
1159
- static VALUE zipruby_archive_locate_name(int argc, VALUE *argv, VALUE self) {
1160
- VALUE fname, flags;
1161
- struct zipruby_archive *p_archive;
1162
- int i_flags = 0;
1163
-
1164
- rb_scan_args(argc, argv, "11", &fname, &flags);
1165
- Check_Type(fname, T_STRING);
1166
-
1167
- if (!NIL_P(flags)) {
1168
- i_flags = NUM2INT(flags);
1169
- }
1170
-
1171
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
1172
- Check_Archive(p_archive);
1173
-
1174
- return INT2NUM(zip_name_locate(p_archive->archive, RSTRING_PTR(fname), i_flags));
1175
- }
1176
-
1177
- /* */
1178
- static VALUE zipruby_archive_get_fcomment(int argc, VALUE *argv, VALUE self) {
1179
- VALUE index, flags;
1180
- struct zipruby_archive *p_archive;
1181
- const char *comment;
1182
- int lenp, i_flags = 0;
1183
-
1184
- rb_scan_args(argc, argv, "11", &index, &flags);
1185
-
1186
- if (!NIL_P(flags)) {
1187
- i_flags = NUM2INT(flags);
1188
- }
1189
-
1190
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
1191
- Check_Archive(p_archive);
1192
-
1193
- // XXX: How is the error checked?
1194
- comment = zip_get_file_comment(p_archive->archive, NUM2INT(index), &lenp, i_flags);
1195
-
1196
- return comment ? rb_str_new(comment, lenp) : Qnil;
1197
- }
1198
-
1199
- /* */
1200
- static VALUE zipruby_archive_set_fcomment(VALUE self, VALUE index, VALUE comment) {
1201
- struct zipruby_archive *p_archive;
1202
- char *s_comment = NULL;
1203
- int len = 0;
1204
-
1205
- if (!NIL_P(comment)) {
1206
- Check_Type(comment, T_STRING);
1207
- s_comment = RSTRING_PTR(comment);
1208
- len = RSTRING_LEN(comment);
1209
- }
1210
-
1211
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
1212
- Check_Archive(p_archive);
1213
-
1214
- if (zip_set_file_comment(p_archive->archive, NUM2INT(index), s_comment, len) == -1) {
1215
- zip_unchange_all(p_archive->archive);
1216
- zip_unchange_archive(p_archive->archive);
1217
- rb_raise(Error, "Comment file failed at %d: %s", NUM2INT(index), zip_strerror(p_archive->archive));
1218
- }
1219
-
1220
- return Qnil;
1221
- }
1222
-
1223
- /* */
1224
- static VALUE zipruby_archive_fdelete(VALUE self, VALUE index) {
1225
- struct zipruby_archive *p_archive;
1226
-
1227
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
1228
- Check_Archive(p_archive);
1229
-
1230
- if (zip_delete(p_archive->archive, NUM2INT(index)) == -1) {
1231
- zip_unchange_all(p_archive->archive);
1232
- zip_unchange_archive(p_archive->archive);
1233
- rb_raise(Error, "Delete file failed at %d: %s", NUM2INT(index), zip_strerror(p_archive->archive));
1234
- }
1235
-
1236
- return Qnil;
1237
- }
1238
-
1239
- /* */
1240
- static VALUE zipruby_archive_frename(VALUE self, VALUE index, VALUE name) {
1241
- struct zipruby_archive *p_archive;
1242
-
1243
- Check_Type(name, T_STRING);
1244
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
1245
- Check_Archive(p_archive);
1246
-
1247
- if (zip_rename(p_archive->archive, NUM2INT(index), RSTRING_PTR(name)) == -1) {
1248
- zip_unchange_all(p_archive->archive);
1249
- zip_unchange_archive(p_archive->archive);
1250
- rb_raise(Error, "Rename file failed at %d: %s", NUM2INT(index), zip_strerror(p_archive->archive));
1251
- }
1252
-
1253
- return Qnil;
1254
- }
1255
-
1256
- /* */
1257
- static VALUE zipruby_archive_funchange(VALUE self, VALUE index) {
1258
- struct zipruby_archive *p_archive;
1259
-
1260
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
1261
- Check_Archive(p_archive);
1262
-
1263
- if (zip_unchange(p_archive->archive, NUM2INT(index)) == -1) {
1264
- zip_unchange_all(p_archive->archive);
1265
- zip_unchange_archive(p_archive->archive);
1266
- rb_raise(Error, "Unchange file failed at %d: %s", NUM2INT(index), zip_strerror(p_archive->archive));
1267
- }
1268
-
1269
- return Qnil;
1270
- }
1271
-
1272
- /* */
1273
- static VALUE zipruby_archive_funchange_all(VALUE self) {
1274
- struct zipruby_archive *p_archive;
1275
-
1276
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
1277
- Check_Archive(p_archive);
1278
-
1279
- if (zip_unchange_all(p_archive->archive) == -1) {
1280
- rb_raise(Error, "Unchange all file failed: %s", zip_strerror(p_archive->archive));
1281
- }
1282
-
1283
- return Qnil;
1284
- }
1285
-
1286
- /* */
1287
- static VALUE zipruby_archive_unchange(VALUE self) {
1288
- struct zipruby_archive *p_archive;
1289
-
1290
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
1291
- Check_Archive(p_archive);
1292
-
1293
- if (zip_unchange_archive(p_archive->archive) == -1) {
1294
- rb_raise(Error, "Unchange archive failed: %s", zip_strerror(p_archive->archive));
1295
- }
1296
-
1297
- return Qnil;
1298
- }
1299
-
1300
- /* */
1301
- static VALUE zipruby_archive_revert(VALUE self) {
1302
- zipruby_archive_funchange_all(self);
1303
- zipruby_archive_unchange(self);
1304
-
1305
- return Qnil;
1306
- }
1307
-
1308
- /* */
1309
- static VALUE zipruby_archive_each(VALUE self) {
1310
- struct zipruby_archive *p_archive;
1311
- int i, num_files;
1312
-
1313
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
1314
- Check_Archive(p_archive);
1315
- num_files = zip_get_num_files(p_archive->archive);
1316
-
1317
- for (i = 0; i < num_files; i++) {
1318
- VALUE file;
1319
- int status;
1320
-
1321
- file = rb_funcall(File, rb_intern("new"), 2, self, INT2NUM(i));
1322
- rb_protect(rb_yield, file, &status);
1323
- rb_funcall(file, rb_intern("close"), 0);
1324
-
1325
- if (status != 0) {
1326
- rb_jump_tag(status);
1327
- }
1328
- }
1329
-
1330
- return Qnil;
1331
- }
1332
-
1333
- /* */
1334
- static VALUE zipruby_archive_commit(VALUE self) {
1335
- struct zipruby_archive *p_archive;
1336
- int changed, survivors;
1337
- int errorp;
1338
-
1339
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
1340
- Check_Archive(p_archive);
1341
-
1342
- changed = _zip_changed(p_archive->archive, &survivors);
1343
-
1344
- if (zip_close(p_archive->archive) == -1) {
1345
- zip_unchange_all(p_archive->archive);
1346
- zip_unchange_archive(p_archive->archive);
1347
- rb_raise(Error, "Commit archive failed: %s", zip_strerror(p_archive->archive));
1348
- }
1349
-
1350
- if (!NIL_P(p_archive->buffer) && changed) {
1351
- rb_funcall(p_archive->buffer, rb_intern("replace"), 1, rb_funcall(self, rb_intern("read"), 0));
1352
- }
1353
-
1354
- p_archive->archive = NULL;
1355
- p_archive->flags = (p_archive->flags & ~(ZIP_CREATE | ZIP_EXCL));
1356
-
1357
- if ((p_archive->archive = zip_open(RSTRING_PTR(p_archive->path), p_archive->flags, &errorp)) == NULL) {
1358
- char errstr[ERRSTR_BUFSIZE];
1359
- zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
1360
- rb_raise(Error, "Commit archive failed: %s", errstr);
1361
- }
1362
-
1363
- return Qnil;
1364
- }
1365
-
1366
- /* */
1367
- static VALUE zipruby_archive_is_open(VALUE self) {
1368
- struct zipruby_archive *p_archive;
1369
-
1370
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
1371
- return (p_archive->archive != NULL) ? Qtrue : Qfalse;
1372
- }
1373
-
1374
- /* */
1375
- static VALUE zipruby_archive_decrypt(VALUE self, VALUE password) {
1376
- VALUE retval;
1377
- struct zipruby_archive *p_archive;
1378
- long pwdlen;
1379
- int changed, survivors;
1380
- int errorp;
1381
-
1382
- Check_Type(password, T_STRING);
1383
- pwdlen = RSTRING_LEN(password);
1384
-
1385
- if (pwdlen < 1) {
1386
- rb_raise(Error, "Decrypt archive failed: Password is empty");
1387
- } else if (pwdlen > 0xff) {
1388
- rb_raise(Error, "Decrypt archive failed: Password is too long");
1389
- }
1390
-
1391
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
1392
- Check_Archive(p_archive);
1393
-
1394
- changed = _zip_changed(p_archive->archive, &survivors);
1395
-
1396
- if (zip_close(p_archive->archive) == -1) {
1397
- zip_unchange_all(p_archive->archive);
1398
- zip_unchange_archive(p_archive->archive);
1399
- rb_raise(Error, "Decrypt archive failed: %s", zip_strerror(p_archive->archive));
1400
- }
1401
-
1402
- if (!NIL_P(p_archive->buffer) && changed) {
1403
- rb_funcall(p_archive->buffer, rb_intern("replace"), 1, rb_funcall(self, rb_intern("read"), 0));
1404
- }
1405
-
1406
- p_archive->archive = NULL;
1407
- p_archive->flags = (p_archive->flags & ~(ZIP_CREATE | ZIP_EXCL));
1408
-
1409
- retval = zipruby_archive_s_decrypt(Archive, p_archive->path, password);
1410
-
1411
- if ((p_archive->archive = zip_open(RSTRING_PTR(p_archive->path), p_archive->flags, &errorp)) == NULL) {
1412
- char errstr[ERRSTR_BUFSIZE];
1413
- zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
1414
- rb_raise(Error, "Decrypt archive failed: %s", errstr);
1415
- }
1416
-
1417
- return retval;
1418
- }
1419
-
1420
- /* */
1421
- static VALUE zipruby_archive_encrypt(VALUE self, VALUE password) {
1422
- VALUE retval;
1423
- struct zipruby_archive *p_archive;
1424
- long pwdlen;
1425
- int changed, survivors;
1426
- int errorp;
1427
-
1428
- Check_Type(password, T_STRING);
1429
- pwdlen = RSTRING_LEN(password);
1430
-
1431
- if (pwdlen < 1) {
1432
- rb_raise(Error, "Encrypt archive failed: Password is empty");
1433
- } else if (pwdlen > 0xff) {
1434
- rb_raise(Error, "Encrypt archive failed: Password is too long");
1435
- }
1436
-
1437
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
1438
- Check_Archive(p_archive);
1439
-
1440
- changed = _zip_changed(p_archive->archive, &survivors);
1441
-
1442
- if (zip_close(p_archive->archive) == -1) {
1443
- zip_unchange_all(p_archive->archive);
1444
- zip_unchange_archive(p_archive->archive);
1445
- rb_raise(Error, "Encrypt archive failed: %s", zip_strerror(p_archive->archive));
1446
- }
1447
-
1448
- if (!NIL_P(p_archive->buffer) && changed) {
1449
- rb_funcall(p_archive->buffer, rb_intern("replace"), 1, rb_funcall(self, rb_intern("read"), 0));
1450
- }
1451
-
1452
- p_archive->archive = NULL;
1453
- p_archive->flags = (p_archive->flags & ~(ZIP_CREATE | ZIP_EXCL));
1454
-
1455
- retval = zipruby_archive_s_encrypt(Archive, p_archive->path, password);
1456
-
1457
- if ((p_archive->archive = zip_open(RSTRING_PTR(p_archive->path), p_archive->flags, &errorp)) == NULL) {
1458
- char errstr[ERRSTR_BUFSIZE];
1459
- zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
1460
- rb_raise(Error, "Encrypt archive failed: %s", errstr);
1461
- }
1462
-
1463
- return retval;
1464
- }
1465
-
1466
- /* */
1467
- static VALUE zipruby_archive_read(VALUE self) {
1468
- VALUE retval = Qnil;
1469
- struct zipruby_archive *p_archive;
1470
- FILE *fzip;
1471
- char buf[DATA_BUFSIZE];
1472
- ssize_t n;
1473
- int block_given;
1474
-
1475
- Data_Get_Struct(self, struct zipruby_archive, p_archive);
1476
-
1477
- if (NIL_P(p_archive->path)) {
1478
- rb_raise(rb_eRuntimeError, "invalid Zip::Archive");
1479
- }
1480
-
1481
- #ifdef _WIN32
1482
- if (fopen_s(&fzip, RSTRING_PTR(p_archive->path), "rb") != 0) {
1483
- rb_raise(Error, "Read archive failed: Cannot open archive");
1484
- }
1485
- #else
1486
- if ((fzip = fopen(RSTRING_PTR(p_archive->path), "rb")) == NULL) {
1487
- rb_raise(Error, "Read archive failed: Cannot open archive");
1488
- }
1489
- #endif
1490
-
1491
- block_given = rb_block_given_p();
1492
-
1493
- while ((n = fread(buf, 1, sizeof(buf), fzip)) > 0) {
1494
- if (block_given) {
1495
- rb_yield(rb_str_new(buf, n));
1496
- } else {
1497
- if (NIL_P(retval)) {
1498
- retval = rb_str_new(buf, n);
1499
- } else {
1500
- rb_str_buf_cat(retval, buf, n);
1501
- }
1502
- }
1503
- }
1504
-
1505
- #ifdef RUBY_WIN32_H
1506
- #undef fclose
1507
- fclose(fzip);
1508
- #define fclose(f) rb_w32_fclose(f)
1509
- #else
1510
- fclose(fzip);
1511
- #endif
1512
-
1513
- if (n == -1) {
1514
- rb_raise(Error, "Read archive failed");
1515
- }
1516
-
1517
- return retval;
1518
- }
1519
- #include "zipruby.h"
1520
- #include "zipruby_error.h"
1521
- #include "ruby.h"
1522
-
1523
- extern VALUE Zip;
1524
- VALUE Error;
1525
-
1526
- void Init_zipruby_error() {
1527
- Error = rb_define_class_under(Zip, "Error", rb_eStandardError);
1528
- }
1529
- #include <errno.h>
1530
-
1531
- #ifndef _WIN32
1532
- #include <alloca.h>
1533
- #else
1534
- #include <malloc.h>
1535
- #endif
1536
-
1537
- #include "zip.h"
1538
- #include "zipint.h"
1539
- #include "zipruby.h"
1540
- #include "zipruby_archive.h"
1541
- #include "zipruby_file.h"
1542
- #include "zipruby_stat.h"
1543
- #include "ruby.h"
1544
-
1545
- #define MIN(a, b) ((a) < (b) ? (a) : (b))
1546
-
1547
- static VALUE zipruby_file(VALUE klass);
1548
- static VALUE zipruby_file_alloc(VALUE klass);
1549
- static void zipruby_file_mark(struct zipruby_file *p);
1550
- static void zipruby_file_free(struct zipruby_file *p);
1551
- static VALUE zipruby_file_initialize(int argc, VALUE *argv, VALUE self);
1552
- static VALUE zipruby_file_close(VALUE self);
1553
- static VALUE zipruby_file_read(int argc, VALUE *argv, VALUE self);
1554
- static VALUE zipruby_file_stat(VALUE self);
1555
- static VALUE zipruby_file_get_comment(int argc, VALUE *argv, VALUE self);
1556
- static VALUE zipruby_file_set_comment(VALUE self, VALUE comment);
1557
- static VALUE zipruby_file_delete(VALUE self);
1558
- static VALUE zipruby_file_rename(VALUE self, VALUE name);
1559
- static VALUE zipruby_file_unchange(VALUE self);
1560
- static VALUE zipruby_file_name(VALUE self);
1561
- static VALUE zipruby_file_index(VALUE self);
1562
- static VALUE zipruby_file_crc(VALUE self);
1563
- static VALUE zipruby_file_size(VALUE self);
1564
- static VALUE zipruby_file_mtime(VALUE self);
1565
- static VALUE zipruby_file_comp_size(VALUE self);
1566
- static VALUE zipruby_file_comp_method(VALUE self);
1567
- static VALUE zipruby_file_encryption_method(VALUE self);
1568
-
1569
- extern VALUE Zip;
1570
- extern VALUE Archive;
1571
- VALUE File;
1572
- extern VALUE Stat;
1573
- extern VALUE Error;
1574
-
1575
- void Init_zipruby_file() {
1576
- File = rb_define_class_under(Zip, "File", rb_cObject);
1577
- rb_define_alloc_func(File, zipruby_file_alloc);
1578
- rb_define_method(File, "initialize", zipruby_file_initialize, -1);
1579
- rb_define_method(File, "close", zipruby_file_close, 0);
1580
- rb_define_method(File, "read", zipruby_file_read, -1);
1581
- rb_define_method(File, "stat", zipruby_file_stat, 0);
1582
- rb_define_method(File, "get_comment", zipruby_file_get_comment, -1);
1583
- rb_define_method(File, "comment", zipruby_file_get_comment, -1);
1584
- rb_define_method(File, "comment=", zipruby_file_set_comment, 1);
1585
- rb_define_method(File, "delete", zipruby_file_delete, 0);
1586
- rb_define_method(File, "rename", zipruby_file_rename, 1);
1587
- rb_define_method(File, "unchange", zipruby_file_unchange, 1);
1588
- rb_define_method(File, "revert", zipruby_file_unchange, 1);
1589
- rb_define_method(File, "name", zipruby_file_name, 0);
1590
- rb_define_method(File, "index", zipruby_file_index, 0);
1591
- rb_define_method(File, "crc", zipruby_file_crc, 0);
1592
- rb_define_method(File, "size", zipruby_file_size, 0);
1593
- rb_define_method(File, "mtime", zipruby_file_mtime, 0);
1594
- rb_define_method(File, "comp_size", zipruby_file_comp_size, 0);
1595
- rb_define_method(File, "comp_method", zipruby_file_comp_method, 0);
1596
- rb_define_method(File, "encryption_method", zipruby_file_encryption_method, 0);
1597
- }
1598
-
1599
- static VALUE zipruby_file_alloc(VALUE klass) {
1600
- struct zipruby_file *p = ALLOC(struct zipruby_file);
1601
-
1602
- p->archive = NULL;
1603
- p->file = NULL;
1604
- p->sb = NULL;
1605
-
1606
- return Data_Wrap_Struct(klass, zipruby_file_mark, zipruby_file_free, p);
1607
- }
1608
-
1609
- static void zipruby_file_mark(struct zipruby_file *p) {
1610
- if (p->archive) { rb_gc_mark(p->v_archive); }
1611
- if (p->sb) { rb_gc_mark(p->v_sb); }
1612
- }
1613
-
1614
- static void zipruby_file_free(struct zipruby_file *p) {
1615
- xfree(p);
1616
- }
1617
-
1618
- /* */
1619
- static VALUE zipruby_file_initialize(int argc, VALUE *argv, VALUE self) {
1620
- VALUE archive, index, flags, stat_flags;
1621
- struct zipruby_archive *p_archive;
1622
- struct zipruby_file *p_file;
1623
- struct zipruby_stat *p_stat;
1624
- struct zip_file *fzip;
1625
- char *fname = NULL;
1626
- int i_index = -1, i_flags = 0;
1627
-
1628
- rb_scan_args(argc, argv, "22", &archive, &index, &flags, &stat_flags);
1629
-
1630
- if (!rb_obj_is_instance_of(archive, Archive)) {
1631
- rb_raise(rb_eTypeError, "wrong argument type %s (expected Zip::Archive)", rb_class2name(CLASS_OF(archive)));
1632
- }
1633
-
1634
- switch (TYPE(index)) {
1635
- case T_STRING: fname = RSTRING_PTR(index); break;
1636
- case T_FIXNUM: i_index = NUM2INT(index); break;
1637
- default:
1638
- rb_raise(rb_eTypeError, "wrong argument type %s (expected String or Fixnum)", rb_class2name(CLASS_OF(index)));
1639
- }
1640
-
1641
- if (!NIL_P(flags)) {
1642
- i_flags = NUM2INT(flags);
1643
- }
1644
-
1645
- Data_Get_Struct(archive, struct zipruby_archive, p_archive);
1646
- Check_Archive(p_archive);
1647
-
1648
- if (fname) {
1649
- fzip = zip_fopen(p_archive->archive, fname, i_flags);
1650
-
1651
- if (fzip == NULL) {
1652
- rb_raise(Error, "Open file failed - %s: %s", fname, zip_strerror(p_archive->archive));
1653
- }
1654
- } else {
1655
- fzip = zip_fopen_index(p_archive->archive, i_index, i_flags);
1656
-
1657
- if (fzip == NULL) {
1658
- rb_raise(Error, "Open file failed at %d: %s", i_index, zip_strerror(p_archive->archive));
1659
- }
1660
- }
1661
-
1662
- Data_Get_Struct(self, struct zipruby_file, p_file);
1663
- p_file->v_archive = archive;
1664
- p_file->archive = p_archive->archive;
1665
- p_file->file = fzip;
1666
- p_file->v_sb = rb_funcall(Stat, rb_intern("new"), 3, archive, index, stat_flags);
1667
- Data_Get_Struct(p_file->v_sb, struct zipruby_stat, p_stat);
1668
- p_file->sb = p_stat->sb;
1669
-
1670
- return Qnil;
1671
- }
1672
-
1673
- /* */
1674
- static VALUE zipruby_file_close(VALUE self) {
1675
- struct zipruby_file *p_file;
1676
- int error;
1677
-
1678
- Data_Get_Struct(self, struct zipruby_file, p_file);
1679
- Check_File(p_file);
1680
-
1681
- if ((error = zip_fclose(p_file->file)) != 0) {
1682
- char errstr[ERRSTR_BUFSIZE];
1683
- zip_unchange(p_file->archive, p_file->sb->index);
1684
- zip_error_to_str(errstr, ERRSTR_BUFSIZE, error, errno);
1685
- rb_raise(Error, "Close file failed: %s", errstr);
1686
- }
1687
-
1688
- p_file->archive = NULL;
1689
- p_file->file = NULL;
1690
- p_file->sb = NULL;
1691
-
1692
- return Qnil;
1693
- }
1694
-
1695
- /* */
1696
- static VALUE zipruby_file_read(int argc, VALUE *argv, VALUE self) {
1697
- VALUE size, retval = Qnil;
1698
- struct zipruby_file *p_file;
1699
- struct zip_stat sb;
1700
- int block_given;
1701
- size_t bytes_left;
1702
- char buf[DATA_BUFSIZE];
1703
- ssize_t n;
1704
-
1705
- rb_scan_args(argc, argv, "01", &size);
1706
- Data_Get_Struct(self, struct zipruby_file, p_file);
1707
- Check_File(p_file);
1708
- zip_stat_init(&sb);
1709
-
1710
- if (p_file->archive->cdir->entry[0].bitflags & ZIP_GPBF_ENCRYPTED) {
1711
- rb_raise(Error, "Read file failed: File encrypted");
1712
- }
1713
-
1714
- if (zip_stat_index(p_file->archive, p_file->sb->index, 0, &sb)) {
1715
- rb_raise(Error, "Read file failed: %s", zip_strerror(p_file->archive));
1716
- }
1717
-
1718
- if (NIL_P(size)) {
1719
- bytes_left = sb.size;
1720
- } else {
1721
- bytes_left = NUM2LONG(size);
1722
- }
1723
-
1724
- if (bytes_left <= 0) {
1725
- return Qnil;
1726
- }
1727
-
1728
- block_given = rb_block_given_p();
1729
-
1730
- while ((n = zip_fread(p_file->file, buf, MIN(bytes_left, sizeof(buf)))) > 0) {
1731
- if (block_given) {
1732
- rb_yield(rb_str_new(buf, n));
1733
- } else {
1734
- if (NIL_P(retval)) {
1735
- retval = rb_str_new(buf, n);
1736
- } else {
1737
- rb_str_buf_cat(retval, buf, n);
1738
- }
1739
- }
1740
-
1741
- bytes_left -= n;
1742
- }
1743
-
1744
- if (n == -1) {
1745
- rb_raise(Error, "Read file failed: %s", zip_file_strerror(p_file->file));
1746
- }
1747
-
1748
- return retval;
1749
- }
1750
-
1751
- /* */
1752
- static VALUE zipruby_file_stat(VALUE self) {
1753
- struct zipruby_file *p_file;
1754
-
1755
- Data_Get_Struct(self, struct zipruby_file, p_file);
1756
- Check_File(p_file);
1757
-
1758
- return p_file->v_sb;
1759
- }
1760
-
1761
- /* */
1762
- static VALUE zipruby_file_get_comment(int argc, VALUE *argv, VALUE self) {
1763
- VALUE flags;
1764
- struct zipruby_file *p_file;
1765
- const char *comment;
1766
- int lenp, i_flags = 0;
1767
-
1768
- rb_scan_args(argc, argv, "01", &flags);
1769
-
1770
- if (!NIL_P(flags)) {
1771
- i_flags = NUM2INT(flags);
1772
- }
1773
-
1774
- Data_Get_Struct(self, struct zipruby_file, p_file);
1775
- Check_File(p_file);
1776
-
1777
- // XXX: How is the error checked?
1778
- comment = zip_get_file_comment(p_file->archive, p_file->sb->index, &lenp, i_flags);
1779
-
1780
- return comment ? rb_str_new(comment, lenp) : Qnil;
1781
- }
1782
-
1783
- /* */
1784
- static VALUE zipruby_file_set_comment(VALUE self, VALUE comment) {
1785
- struct zipruby_file *p_file;
1786
- char *s_comment = NULL;
1787
- int len = 0;
1788
-
1789
- if (!NIL_P(comment)) {
1790
- Check_Type(comment, T_STRING);
1791
- s_comment = RSTRING_PTR(comment);
1792
- len = RSTRING_LEN(comment);
1793
- }
1794
-
1795
- Data_Get_Struct(self, struct zipruby_file, p_file);
1796
- Check_File(p_file);
1797
-
1798
- if (zip_set_file_comment(p_file->archive, p_file->sb->index, s_comment, len) == -1) {
1799
- zip_unchange_all(p_file->archive);
1800
- zip_unchange_archive(p_file->archive);
1801
- rb_raise(Error, "Comment file failed - %s: %s", p_file->sb->name, zip_strerror(p_file->archive));
1802
- }
1803
-
1804
- return Qnil;
1805
- }
1806
-
1807
- /* */
1808
- static VALUE zipruby_file_delete(VALUE self) {
1809
- struct zipruby_file *p_file;
1810
-
1811
- Data_Get_Struct(self, struct zipruby_file, p_file);
1812
- Check_File(p_file);
1813
-
1814
- if (zip_delete(p_file->archive, p_file->sb->index) == -1) {
1815
- zip_unchange_all(p_file->archive);
1816
- zip_unchange_archive(p_file->archive);
1817
- rb_raise(Error, "Delete file failed - %s: %s", p_file->sb->name, zip_strerror(p_file->archive));
1818
- }
1819
-
1820
- return Qnil;
1821
- }
1822
-
1823
- /* */
1824
- static VALUE zipruby_file_rename(VALUE self, VALUE name) {
1825
- struct zipruby_file *p_file;
1826
-
1827
- Check_Type(name, T_STRING);
1828
- Data_Get_Struct(self, struct zipruby_file, p_file);
1829
- Check_File(p_file);
1830
-
1831
- if (zip_rename(p_file->archive, p_file->sb->index, RSTRING_PTR(name)) == -1) {
1832
- zip_unchange_all(p_file->archive);
1833
- zip_unchange_archive(p_file->archive);
1834
- rb_raise(Error, "Rename file failed - %s: %s", p_file->sb->name, zip_strerror(p_file->archive));
1835
- }
1836
-
1837
- return Qnil;
1838
- }
1839
-
1840
- /* */
1841
- static VALUE zipruby_file_unchange(VALUE self) {
1842
- struct zipruby_file *p_file;
1843
-
1844
- Data_Get_Struct(self, struct zipruby_file, p_file);
1845
- Check_File(p_file);
1846
-
1847
- if (zip_unchange(p_file->archive, p_file->sb->index) == -1) {
1848
- rb_raise(Error, "Unchange file failed - %s: %s", p_file->sb->name, zip_strerror(p_file->archive));
1849
- }
1850
-
1851
- return Qnil;
1852
- }
1853
-
1854
- /* */
1855
- static VALUE zipruby_file_name(VALUE self) {
1856
- struct zipruby_file *p_file;
1857
-
1858
- Data_Get_Struct(self, struct zipruby_file, p_file);
1859
- Check_File(p_file);
1860
-
1861
- return rb_funcall(p_file->v_sb, rb_intern("name"), 0);
1862
- }
1863
-
1864
- /* */
1865
- static VALUE zipruby_file_index(VALUE self) {
1866
- struct zipruby_file *p_file;
1867
-
1868
- Data_Get_Struct(self, struct zipruby_file, p_file);
1869
- Check_File(p_file);
1870
-
1871
- return rb_funcall(p_file->v_sb, rb_intern("index"), 0);
1872
- }
1873
-
1874
- /* */
1875
- static VALUE zipruby_file_crc(VALUE self) {
1876
- struct zipruby_file *p_file;
1877
-
1878
- Data_Get_Struct(self, struct zipruby_file, p_file);
1879
- Check_File(p_file);
1880
-
1881
- return rb_funcall(p_file->v_sb, rb_intern("crc"), 0);
1882
- }
1883
-
1884
- /* */
1885
- static VALUE zipruby_file_size(VALUE self) {
1886
- struct zipruby_file *p_file;
1887
-
1888
- Data_Get_Struct(self, struct zipruby_file, p_file);
1889
- Check_File(p_file);
1890
-
1891
- return rb_funcall(p_file->v_sb, rb_intern("size"), 0);
1892
- }
1893
-
1894
- /* */
1895
- static VALUE zipruby_file_mtime(VALUE self) {
1896
- struct zipruby_file *p_file;
1897
-
1898
- Data_Get_Struct(self, struct zipruby_file, p_file);
1899
- Check_File(p_file);
1900
-
1901
- return rb_funcall(p_file->v_sb, rb_intern("mtime"), 0);
1902
- }
1903
-
1904
- /* */
1905
- static VALUE zipruby_file_comp_size(VALUE self) {
1906
- struct zipruby_file *p_file;
1907
-
1908
- Data_Get_Struct(self, struct zipruby_file, p_file);
1909
- Check_File(p_file);
1910
-
1911
- return rb_funcall(p_file->v_sb, rb_intern("comp_size"), 0);
1912
- }
1913
-
1914
- /* */
1915
- static VALUE zipruby_file_comp_method(VALUE self) {
1916
- struct zipruby_file *p_file;
1917
-
1918
- Data_Get_Struct(self, struct zipruby_file, p_file);
1919
- Check_File(p_file);
1920
-
1921
- return rb_funcall(p_file->v_sb, rb_intern("comp_method"), 0);
1922
- }
1923
-
1924
- /* */
1925
- static VALUE zipruby_file_encryption_method(VALUE self) {
1926
- struct zipruby_file *p_file;
1927
-
1928
- Data_Get_Struct(self, struct zipruby_file, p_file);
1929
- Check_File(p_file);
1930
-
1931
- return rb_funcall(p_file->v_sb, rb_intern("encryption_method"), 0);
1932
- }
1933
- #include "zip.h"
1934
- #include "zipruby.h"
1935
- #include "zipruby_archive.h"
1936
- #include "zipruby_stat.h"
1937
- #include "ruby.h"
1938
-
1939
- static VALUE zipruby_stat_alloc(VALUE klass);
1940
- static void zipruby_stat_free(struct zipruby_stat *p);
1941
- static VALUE zipruby_stat_initialize(int argc, VALUE *argv, VALUE self);
1942
- static VALUE zipruby_stat_name(VALUE self);
1943
- static VALUE zipruby_stat_index(VALUE self);
1944
- static VALUE zipruby_stat_crc(VALUE self);
1945
- static VALUE zipruby_stat_size(VALUE self);
1946
- static VALUE zipruby_stat_mtime(VALUE self);
1947
- static VALUE zipruby_stat_comp_size(VALUE self);
1948
- static VALUE zipruby_stat_comp_method(VALUE self);
1949
- static VALUE zipruby_stat_encryption_method(VALUE self);
1950
-
1951
- extern VALUE Zip;
1952
- extern VALUE Archive;
1953
- VALUE Stat;
1954
- extern VALUE Error;
1955
-
1956
- void Init_zipruby_stat() {
1957
- Stat = rb_define_class_under(Zip, "Stat", rb_cObject);
1958
- rb_define_alloc_func(Stat, zipruby_stat_alloc);
1959
- rb_define_method(Stat, "initialize", zipruby_stat_initialize, -1);
1960
- rb_define_method(Stat, "name", zipruby_stat_name, 0);
1961
- rb_define_method(Stat, "index", zipruby_stat_index, 0);
1962
- rb_define_method(Stat, "crc", zipruby_stat_crc, 0);
1963
- rb_define_method(Stat, "size", zipruby_stat_size, 0);
1964
- rb_define_method(Stat, "mtime", zipruby_stat_mtime, 0);
1965
- rb_define_method(Stat, "comp_size", zipruby_stat_comp_size, 0);
1966
- rb_define_method(Stat, "comp_method", zipruby_stat_comp_method, 0);
1967
- rb_define_method(Stat, "encryption_method", zipruby_stat_encryption_method, 0);
1968
- }
1969
-
1970
- static VALUE zipruby_stat_alloc(VALUE klass) {
1971
- struct zipruby_stat *p = ALLOC(struct zipruby_stat);
1972
-
1973
- p->sb = ALLOC(struct zip_stat);
1974
- zip_stat_init(p->sb);
1975
-
1976
- return Data_Wrap_Struct(klass, 0, zipruby_stat_free, p);
1977
- }
1978
-
1979
- static void zipruby_stat_free(struct zipruby_stat *p) {
1980
- xfree(p->sb);
1981
- xfree(p);
1982
- }
1983
-
1984
- /* */
1985
- static VALUE zipruby_stat_initialize(int argc, VALUE *argv, VALUE self) {
1986
- VALUE archive, index, flags;
1987
- struct zipruby_archive *p_archive;
1988
- struct zipruby_stat *p_stat;
1989
- char *fname = NULL;
1990
- int i_index = -1, i_flags = 0;
1991
-
1992
- rb_scan_args(argc, argv, "21", &archive, &index, &flags);
1993
-
1994
- if (!rb_obj_is_instance_of(archive, Archive)) {
1995
- rb_raise(rb_eTypeError, "wrong argument type %s (expected Zip::Archive)", rb_class2name(CLASS_OF(archive)));
1996
- }
1997
-
1998
- switch (TYPE(index)) {
1999
- case T_STRING: fname = RSTRING_PTR(index); break;
2000
- case T_FIXNUM: i_index = NUM2INT(index); break;
2001
- default:
2002
- rb_raise(rb_eTypeError, "wrong argument type %s (expected String or Fixnum)", rb_class2name(CLASS_OF(index)));
2003
- }
2004
-
2005
- if (!NIL_P(flags)) {
2006
- i_flags = NUM2INT(flags);
2007
- }
2008
-
2009
- Data_Get_Struct(archive, struct zipruby_archive, p_archive);
2010
- Check_Archive(p_archive);
2011
- Data_Get_Struct(self, struct zipruby_stat, p_stat);
2012
-
2013
- if (fname) {
2014
- if (zip_stat(p_archive->archive, fname, i_flags, p_stat->sb) != 0) {
2015
- rb_raise(Error, "Obtain file status failed - %s: %s", fname, zip_strerror(p_archive->archive));
2016
- }
2017
- } else {
2018
- if (zip_stat_index(p_archive->archive, i_index, i_flags, p_stat->sb) != 0) {
2019
- rb_raise(Error, "Obtain file status failed at %d: %s", i_index, zip_strerror(p_archive->archive));
2020
- }
2021
- }
2022
-
2023
- return Qnil;
2024
- }
2025
-
2026
- /* */
2027
- static VALUE zipruby_stat_name(VALUE self) {
2028
- struct zipruby_stat *p_stat;
2029
-
2030
- Data_Get_Struct(self, struct zipruby_stat, p_stat);
2031
-
2032
- return p_stat->sb->name ? rb_str_new2(p_stat->sb->name) : Qnil;
2033
- }
2034
-
2035
- /* */
2036
- static VALUE zipruby_stat_index(VALUE self) {
2037
- struct zipruby_stat *p_stat;
2038
-
2039
- Data_Get_Struct(self, struct zipruby_stat, p_stat);
2040
-
2041
- return INT2NUM(p_stat->sb->index);
2042
- }
2043
-
2044
- /* */
2045
- static VALUE zipruby_stat_crc(VALUE self) {
2046
- struct zipruby_stat *p_stat;
2047
-
2048
- Data_Get_Struct(self, struct zipruby_stat, p_stat);
2049
-
2050
- return UINT2NUM(p_stat->sb->crc);
2051
- }
2052
-
2053
- /* */
2054
- static VALUE zipruby_stat_size(VALUE self) {
2055
- struct zipruby_stat *p_stat;
2056
-
2057
- Data_Get_Struct(self, struct zipruby_stat, p_stat);
2058
-
2059
- return LONG2NUM(p_stat->sb->size);
2060
- }
2061
-
2062
- /* */
2063
- static VALUE zipruby_stat_mtime(VALUE self) {
2064
- struct zipruby_stat *p_stat;
2065
-
2066
- Data_Get_Struct(self, struct zipruby_stat, p_stat);
2067
-
2068
- return rb_funcall(rb_cTime, rb_intern("at"), 1, LONG2NUM((long) p_stat->sb->mtime));
2069
- }
2070
-
2071
- /* */
2072
- static VALUE zipruby_stat_comp_size(VALUE self) {
2073
- struct zipruby_stat *p_stat;
2074
-
2075
- Data_Get_Struct(self, struct zipruby_stat, p_stat);
2076
-
2077
- return LONG2NUM(p_stat->sb->comp_size);
2078
- }
2079
-
2080
- /* */
2081
- static VALUE zipruby_stat_comp_method(VALUE self) {
2082
- struct zipruby_stat *p_stat;
2083
-
2084
- Data_Get_Struct(self, struct zipruby_stat, p_stat);
2085
-
2086
- return INT2NUM(p_stat->sb->comp_method);
2087
- }
2088
-
2089
- /* */
2090
- static VALUE zipruby_stat_encryption_method(VALUE self) {
2091
- struct zipruby_stat *p_stat;
2092
-
2093
- Data_Get_Struct(self, struct zipruby_stat, p_stat);
2094
-
2095
- return INT2NUM(p_stat->sb->encryption_method);
2096
- }
2097
- #include "ruby.h"
2098
- #include "zip.h"
2099
- #include "zipruby.h"
2100
- #include "zipruby_zip.h"
2101
-
2102
- VALUE Zip;
2103
-
2104
- void Init_zipruby_zip() {
2105
- Zip = rb_define_module("Zip");
2106
- rb_define_const(Zip, "VERSION", rb_str_new2(VERSION));
2107
-
2108
- rb_define_const(Zip, "CREATE", INT2NUM(ZIP_CREATE));
2109
- rb_define_const(Zip, "EXCL", INT2NUM(ZIP_EXCL));
2110
- rb_define_const(Zip, "CHECKCONS", INT2NUM(ZIP_CHECKCONS));
2111
- rb_define_const(Zip, "TRUNC", INT2NUM(ZIP_TRUNC));
2112
-
2113
- rb_define_const(Zip, "FL_NOCASE", INT2NUM(ZIP_FL_NOCASE));
2114
- rb_define_const(Zip, "FL_NODIR", INT2NUM(ZIP_FL_NODIR));
2115
- rb_define_const(Zip, "FL_COMPRESSED", INT2NUM(ZIP_FL_COMPRESSED));
2116
- rb_define_const(Zip, "FL_UNCHANGED", INT2NUM(ZIP_FL_UNCHANGED));
2117
-
2118
- rb_define_const(Zip, "CM_DEFAULT" , INT2NUM(ZIP_CM_DEFAULT));
2119
- rb_define_const(Zip, "CM_STORE", INT2NUM(ZIP_CM_STORE));
2120
- rb_define_const(Zip, "CM_SHRINK", INT2NUM(ZIP_CM_SHRINK));
2121
- rb_define_const(Zip, "CM_REDUCE_1", INT2NUM(ZIP_CM_REDUCE_1));
2122
- rb_define_const(Zip, "CM_REDUCE_2", INT2NUM(ZIP_CM_REDUCE_2));
2123
- rb_define_const(Zip, "CM_REDUCE_3", INT2NUM(ZIP_CM_REDUCE_3));
2124
- rb_define_const(Zip, "CM_REDUCE_4", INT2NUM(ZIP_CM_REDUCE_4));
2125
- rb_define_const(Zip, "CM_IMPLODE", INT2NUM(ZIP_CM_IMPLODE));
2126
- rb_define_const(Zip, "CM_DEFLATE", INT2NUM(ZIP_CM_DEFLATE));
2127
- rb_define_const(Zip, "CM_DEFLATE64", INT2NUM(ZIP_CM_DEFLATE64));
2128
- rb_define_const(Zip, "CM_PKWARE_IMPLODE", INT2NUM(ZIP_CM_PKWARE_IMPLODE));
2129
- rb_define_const(Zip, "CM_BZIP2", INT2NUM(ZIP_CM_BZIP2));
2130
-
2131
- rb_define_const(Zip, "EM_NONE", INT2NUM(ZIP_EM_NONE));
2132
- rb_define_const(Zip, "EM_TRAD_PKWARE", INT2NUM(ZIP_EM_TRAD_PKWARE));
2133
- // XXX: Strong Encryption Header not parsed yet
2134
- }
2135
- #include <string.h>
2136
-
2137
- #include "zip.h"
2138
- #include "zipint.h"
2139
- #include "zipruby_zip_source_proc.h"
2140
- #include "ruby.h"
2141
-
2142
- static VALUE proc_call(VALUE proc) {
2143
- return rb_funcall(proc, rb_intern("call"), 0);
2144
- }
2145
-
2146
- static ssize_t read_proc(void *state, void *data, size_t len, enum zip_source_cmd cmd) {
2147
- struct read_proc *z;
2148
- VALUE src;
2149
- char *buf;
2150
- size_t n;
2151
-
2152
- z = (struct read_proc *) state;
2153
- buf = (char *) data;
2154
-
2155
- switch (cmd) {
2156
- case ZIP_SOURCE_OPEN:
2157
- return 0;
2158
-
2159
- case ZIP_SOURCE_READ:
2160
- src = rb_protect(proc_call, z->proc, NULL);
2161
-
2162
- if (TYPE(src) != T_STRING) {
2163
- return 0;
2164
- }
2165
-
2166
- n = RSTRING_LEN(src);
2167
-
2168
- if (n > 0) {
2169
- n = (n > len) ? len : n;
2170
- memcpy(buf, RSTRING_PTR(src), n);
2171
- }
2172
-
2173
- return n;
2174
-
2175
- case ZIP_SOURCE_CLOSE:
2176
- return 0;
2177
-
2178
- case ZIP_SOURCE_STAT:
2179
- {
2180
- struct zip_stat *st = (struct zip_stat *)data;
2181
- zip_stat_init(st);
2182
- st->mtime = NUM2LONG(rb_funcall(z->mtime, rb_intern("tv_sec"), 0));
2183
- return sizeof(*st);
2184
- }
2185
-
2186
- case ZIP_SOURCE_ERROR:
2187
- return 0;
2188
-
2189
- case ZIP_SOURCE_FREE:
2190
- free(z);
2191
- return 0;
2192
- }
2193
-
2194
- return -1;
2195
- }
2196
-
2197
- struct zip_source *zip_source_proc(struct zip *za, struct read_proc *z) {
2198
- struct zip_source *zs;
2199
- zs = zip_source_function(za, read_proc, z);
2200
- return zs;
2201
- }
2
+ #include <stdio.h>
3
+ #include <stdlib.h>
4
+ #include <string.h>
5
+ #include <sys/types.h>
6
+ #include <sys/stat.h>
7
+
8
+ #ifdef _WIN32
9
+ #if RUBY_VERSION_MAJOR == 1 && RUBY_VERSION_MINOR == 8
10
+ #include <windows.h>
11
+ #endif
12
+ #include <io.h>
13
+ #include <fcntl.h>
14
+ #include <share.h>
15
+ #endif
16
+
17
+ #include "tmpfile.h"
18
+ #include "ruby.h"
19
+
20
+ #ifndef _WIN32
21
+ #ifndef HAVE_MKSTEMP
22
+ int _zip_mkstemp(char *);
23
+ #define mkstemp _zip_mkstemp
24
+ #endif
25
+ #endif
26
+
27
+ static int write_from_proc(VALUE proc, int fd);
28
+ static VALUE proc_call(VALUE proc);
29
+
30
+ char *zipruby_tmpnam(void *data, int len) {
31
+ char *filnam;
32
+
33
+ #ifdef _WIN32
34
+ int fd;
35
+ char tmpdirnam[_MAX_PATH];
36
+ char tmpfilnam[_MAX_PATH];
37
+ int namlen;
38
+
39
+ memset(tmpdirnam, 0, _MAX_PATH);
40
+
41
+ if (GetTempPathA(_MAX_PATH, tmpdirnam) == 0) {
42
+ return NULL;
43
+ }
44
+
45
+ memset(tmpfilnam, 0, _MAX_PATH);
46
+
47
+ if (GetTempFileNameA(tmpdirnam, "zrb", 0, tmpfilnam) == 0) {
48
+ return NULL;
49
+ }
50
+
51
+ namlen = strlen(tmpfilnam) + 1;
52
+
53
+ if ((filnam = calloc(namlen, sizeof(char))) == NULL) {
54
+ return NULL;
55
+ }
56
+
57
+ if (strcpy_s(filnam, namlen, tmpfilnam) != 0) {
58
+ free(filnam);
59
+ return NULL;
60
+ }
61
+
62
+ if (data) {
63
+ if ((_sopen_s(&fd, filnam, _O_WRONLY | _O_BINARY, _SH_DENYRD, _S_IWRITE)) != 0) {
64
+ free(filnam);
65
+ return NULL;
66
+ }
67
+
68
+ if (len < 0) {
69
+ if (write_from_proc((VALUE) data, fd) == -1) {
70
+ free(filnam);
71
+ return NULL;
72
+ }
73
+ } else {
74
+ if (_write(fd, data, len) == -1) {
75
+ free(filnam);
76
+ return NULL;
77
+ }
78
+ }
79
+
80
+ if (_close(fd) == -1) {
81
+ free(filnam);
82
+ return NULL;
83
+ }
84
+ }
85
+ #else
86
+ int fd;
87
+ #ifdef P_tmpdir
88
+ int namlen = 16 + strlen(P_tmpdir);
89
+ char *dirnam = P_tmpdir;
90
+ #else
91
+ int namlen = 20;
92
+ char *dirnam = "/tmp";
93
+ #endif
94
+
95
+ if ((filnam = calloc(namlen, sizeof(char))) == NULL) {
96
+ return NULL;
97
+ }
98
+
99
+ strcpy(filnam, dirnam);
100
+ strcat(filnam, "/zipruby.XXXXXX");
101
+
102
+ if ((fd = mkstemp(filnam)) == -1) {
103
+ free(filnam);
104
+ return NULL;
105
+ }
106
+
107
+ if (data) {
108
+ if (len < 0) {
109
+ if (write_from_proc((VALUE) data, fd) == -1) {
110
+ free(filnam);
111
+ return NULL;
112
+ }
113
+ } else {
114
+ if (write(fd, data, len) == -1) {
115
+ free(filnam);
116
+ return NULL;
117
+ }
118
+ }
119
+ }
120
+
121
+ if (close(fd) == -1) {
122
+ free(filnam);
123
+ return NULL;
124
+ }
125
+ #endif
126
+
127
+ return filnam;
128
+ }
129
+
130
+ void zipruby_rmtmp(const char *tmpfilnam) {
131
+ struct stat st;
132
+
133
+ if (!tmpfilnam) {
134
+ return;
135
+ }
136
+
137
+ if (stat(tmpfilnam, &st) != 0) {
138
+ return;
139
+ }
140
+
141
+ #ifdef _WIN32
142
+ _unlink(tmpfilnam);
143
+ #else
144
+ unlink(tmpfilnam);
145
+ #endif
146
+ }
147
+
148
+ static int write_from_proc(VALUE proc, int fd) {
149
+ while (1) {
150
+ VALUE src = rb_protect(proc_call, proc, NULL);
151
+
152
+ if (TYPE(src) != T_STRING) {
153
+ break;
154
+ }
155
+
156
+ if (RSTRING_LEN(src) < 1) {
157
+ break;
158
+ }
159
+
160
+ #ifdef _WIN32
161
+ if (_write(fd, RSTRING_PTR(src), RSTRING_LEN(src)) == -1) {
162
+ return -1;
163
+ }
164
+ #else
165
+ if (write(fd, RSTRING_PTR(src), RSTRING_LEN(src)) == -1) {
166
+ return -1;
167
+ }
168
+ #endif
169
+ }
170
+
171
+ return 0;
172
+ }
173
+
174
+ static VALUE proc_call(VALUE proc) {
175
+ return rb_funcall(proc, rb_intern("call"), 0);
176
+ }
177
+ #ifdef _WIN32
178
+ __declspec(dllexport) void Init_zipruby(void);
179
+ #endif
180
+
181
+ #include "zipruby.h"
182
+ #include "zipruby_zip.h"
183
+ #include "zipruby_archive.h"
184
+ #include "zipruby_file.h"
185
+ #include "zipruby_stat.h"
186
+ #include "zipruby_error.h"
187
+
188
+ void Init_zipruby() {
189
+ Init_zipruby_zip();
190
+ Init_zipruby_archive();
191
+ Init_zipruby_file();
192
+ Init_zipruby_stat();
193
+ Init_zipruby_error();
194
+ }
195
+ #include <errno.h>
196
+
197
+ #include "zip.h"
198
+ #include "zipruby.h"
199
+ #include "zipruby_archive.h"
200
+ #include "zipruby_zip_source_proc.h"
201
+ #include "tmpfile.h"
202
+ #include "ruby.h"
203
+ #ifndef RUBY_VM
204
+ #include "rubyio.h"
205
+ #endif
206
+
207
+ static VALUE zipruby_archive_alloc(VALUE klass);
208
+ static void zipruby_archive_mark(struct zipruby_archive *p);
209
+ static void zipruby_archive_free(struct zipruby_archive *p);
210
+ static VALUE zipruby_archive_s_open(int argc, VALUE *argv, VALUE self);
211
+ static VALUE zipruby_archive_s_open_buffer(int argc, VALUE *argv, VALUE self);
212
+ static VALUE zipruby_archive_s_decrypt(VALUE self, VALUE path, VALUE password);
213
+ static VALUE zipruby_archive_s_encrypt(VALUE self, VALUE path, VALUE password);
214
+ static VALUE zipruby_archive_close(VALUE self);
215
+ static VALUE zipruby_archive_num_files(VALUE self);
216
+ static VALUE zipruby_archive_get_name(int argc, VALUE *argv, VALUE self);
217
+ static VALUE zipruby_archive_fopen(int argc, VALUE *argv, VALUE self);
218
+ static VALUE zipruby_archive_get_stat(int argc, VALUE *argv, VALUE self);
219
+ static VALUE zipruby_archive_add_buffer(VALUE self, VALUE name, VALUE source);
220
+ static VALUE zipruby_archive_add_file(int argc, VALUE *argv, VALUE self);
221
+ static VALUE zipruby_archive_add_io(VALUE self, VALUE name, VALUE io);
222
+ static VALUE zipruby_archive_add_function(int argc, VALUE *argv, VALUE self);
223
+ static VALUE zipruby_archive_replace_buffer(int argc, VALUE *argv, VALUE self);
224
+ static VALUE zipruby_archive_replace_file(int argc, VALUE* argv, VALUE self);
225
+ static VALUE zipruby_archive_replace_io(int argc, VALUE* argv, VALUE self);
226
+ static VALUE zipruby_archive_replace_function(int argc, VALUE *argv, VALUE self);
227
+ static VALUE zipruby_archive_add_or_replace_buffer(int argc, VALUE *argv, VALUE self);
228
+ static VALUE zipruby_archive_add_or_replace_file(int argc, VALUE *argv, VALUE self);
229
+ static VALUE zipruby_archive_add_or_replace_io(int argc, VALUE *argv, VALUE self);
230
+ static VALUE zipruby_archive_add_or_replace_function(int argc, VALUE *argv, VALUE self);
231
+ static VALUE zipruby_archive_update(int argc, VALUE *argv, VALUE self);
232
+ static VALUE zipruby_archive_get_comment(int argc, VALUE *argv, VALUE self);
233
+ static VALUE zipruby_archive_set_comment(VALUE self, VALUE comment);
234
+ static VALUE zipruby_archive_locate_name(int argc, VALUE *argv, VALUE self);
235
+ static VALUE zipruby_archive_get_fcomment(int argc, VALUE *argv, VALUE self);
236
+ static VALUE zipruby_archive_set_fcomment(VALUE self, VALUE index, VALUE comment);
237
+ static VALUE zipruby_archive_fdelete(VALUE self, VALUE index);
238
+ static VALUE zipruby_archive_frename(VALUE self, VALUE index, VALUE name);
239
+ static VALUE zipruby_archive_funchange(VALUE self, VALUE index);
240
+ static VALUE zipruby_archive_funchange_all(VALUE self);
241
+ static VALUE zipruby_archive_unchange(VALUE self);
242
+ static VALUE zipruby_archive_revert(VALUE self);
243
+ static VALUE zipruby_archive_each(VALUE self);
244
+ static VALUE zipruby_archive_commit(VALUE self);
245
+ static VALUE zipruby_archive_is_open(VALUE self);
246
+ static VALUE zipruby_archive_decrypt(VALUE self, VALUE password);
247
+ static VALUE zipruby_archive_encrypt(VALUE self, VALUE password);
248
+ static VALUE zipruby_archive_read(VALUE self);
249
+
250
+ extern VALUE Zip;
251
+ VALUE Archive;
252
+ extern VALUE File;
253
+ extern VALUE Stat;
254
+ extern VALUE Error;
255
+
256
+ void Init_zipruby_archive() {
257
+ Archive = rb_define_class_under(Zip, "Archive", rb_cObject);
258
+ rb_define_alloc_func(Archive, zipruby_archive_alloc);
259
+ rb_include_module(Archive, rb_mEnumerable);
260
+ rb_define_singleton_method(Archive, "open", zipruby_archive_s_open, -1);
261
+ rb_define_singleton_method(Archive, "open_buffer", zipruby_archive_s_open_buffer, -1);
262
+ rb_define_singleton_method(Archive, "decrypt", zipruby_archive_s_decrypt, 2);
263
+ rb_define_singleton_method(Archive, "encrypt", zipruby_archive_s_encrypt, 2);
264
+ rb_define_method(Archive, "close", zipruby_archive_close, 0);
265
+ rb_define_method(Archive, "num_files", zipruby_archive_num_files, 0);
266
+ rb_define_method(Archive, "get_name", zipruby_archive_get_name, -1);
267
+ rb_define_method(Archive, "fopen", zipruby_archive_fopen, -1);
268
+ rb_define_method(Archive, "get_stat", zipruby_archive_get_stat, -1);
269
+ rb_define_method(Archive, "add_buffer", zipruby_archive_add_buffer, 2);
270
+ rb_define_method(Archive, "add_file", zipruby_archive_add_file, -1);
271
+ rb_define_method(Archive, "add_io", zipruby_archive_add_io, 2);
272
+ rb_define_method(Archive, "add", zipruby_archive_add_function, -1);
273
+ rb_define_method(Archive, "replace_buffer", zipruby_archive_replace_buffer, -1);
274
+ rb_define_method(Archive, "replace_file", zipruby_archive_replace_file, -1);
275
+ rb_define_method(Archive, "replace_io", zipruby_archive_replace_io, -1);
276
+ rb_define_method(Archive, "replace", zipruby_archive_replace_function, -1);
277
+ rb_define_method(Archive, "add_or_replace_buffer", zipruby_archive_add_or_replace_buffer, -1);
278
+ rb_define_method(Archive, "add_or_replace_file", zipruby_archive_add_or_replace_file, -1);
279
+ rb_define_method(Archive, "add_or_replace_io", zipruby_archive_add_or_replace_io, -1);
280
+ rb_define_method(Archive, "add_or_replace", zipruby_archive_add_or_replace_function, -1);
281
+ rb_define_method(Archive, "update", zipruby_archive_update, -1);
282
+ rb_define_method(Archive, "<<", zipruby_archive_add_io, 2);
283
+ rb_define_method(Archive, "get_comment", zipruby_archive_get_comment, -1);
284
+ rb_define_method(Archive, "comment", zipruby_archive_get_comment, -1);
285
+ rb_define_method(Archive, "comment=", zipruby_archive_set_comment, 1);
286
+ rb_define_method(Archive, "locate_name", zipruby_archive_locate_name, -1);
287
+ rb_define_method(Archive, "get_fcomment", zipruby_archive_get_fcomment, -1);
288
+ rb_define_method(Archive, "set_fcomment", zipruby_archive_set_fcomment, 2);
289
+ rb_define_method(Archive, "fdelete", zipruby_archive_fdelete, 1);
290
+ rb_define_method(Archive, "frename", zipruby_archive_frename, 2);
291
+ rb_define_method(Archive, "funchange", zipruby_archive_funchange, 1);
292
+ rb_define_method(Archive, "funchange_all", zipruby_archive_funchange_all, 0);
293
+ rb_define_method(Archive, "unchange", zipruby_archive_unchange, 0);
294
+ rb_define_method(Archive, "frevert", zipruby_archive_unchange, 1);
295
+ rb_define_method(Archive, "revert", zipruby_archive_revert, 0);
296
+ rb_define_method(Archive, "each", zipruby_archive_each, 0);
297
+ rb_define_method(Archive, "commit", zipruby_archive_commit, 0);
298
+ rb_define_method(Archive, "open?", zipruby_archive_is_open, 0);
299
+ rb_define_method(Archive, "decrypt", zipruby_archive_decrypt, 1);
300
+ rb_define_method(Archive, "encrypt", zipruby_archive_encrypt, 1);
301
+ rb_define_method(Archive, "read", zipruby_archive_read, 0);
302
+ }
303
+
304
+ static VALUE zipruby_archive_alloc(VALUE klass) {
305
+ struct zipruby_archive *p = ALLOC(struct zipruby_archive);
306
+
307
+ p->archive = NULL;
308
+ p->path = Qnil;
309
+ p->flags = 0;
310
+ p->tmpfilnam = NULL;
311
+ p->buffer = Qnil;
312
+
313
+ return Data_Wrap_Struct(klass, zipruby_archive_mark, zipruby_archive_free, p);
314
+ }
315
+
316
+ static void zipruby_archive_mark(struct zipruby_archive *p) {
317
+ rb_gc_mark(p->path);
318
+ rb_gc_mark(p->buffer);
319
+ }
320
+
321
+ static void zipruby_archive_free(struct zipruby_archive *p) {
322
+ if (p->tmpfilnam) {
323
+ zipruby_rmtmp(p->tmpfilnam);
324
+ free(p->tmpfilnam);
325
+ }
326
+
327
+ xfree(p);
328
+ }
329
+
330
+ /* */
331
+ static VALUE zipruby_archive_s_open(int argc, VALUE *argv, VALUE self) {
332
+ VALUE path, flags;
333
+ VALUE archive;
334
+ struct zipruby_archive *p_archive;
335
+ int i_flags = 0;
336
+ int errorp;
337
+
338
+ rb_scan_args(argc, argv, "11", &path, &flags);
339
+ Check_Type(path, T_STRING);
340
+
341
+ if (!NIL_P(flags)) {
342
+ i_flags = NUM2INT(flags);
343
+ }
344
+
345
+ archive = rb_funcall(Archive, rb_intern("new"), 0);
346
+ Data_Get_Struct(archive, struct zipruby_archive, p_archive);
347
+
348
+ if ((p_archive->archive = zip_open(RSTRING_PTR(path), i_flags, &errorp)) == NULL) {
349
+ char errstr[ERRSTR_BUFSIZE];
350
+ zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
351
+ rb_raise(Error, "Open archive failed - %s: %s", RSTRING_PTR(path), errstr);
352
+ }
353
+
354
+ p_archive->path = path;
355
+ p_archive->flags = i_flags;
356
+
357
+ if (rb_block_given_p()) {
358
+ VALUE retval;
359
+ int status;
360
+
361
+ retval = rb_protect(rb_yield, archive, &status);
362
+ zipruby_archive_close(archive);
363
+
364
+ if (status != 0) {
365
+ rb_jump_tag(status);
366
+ }
367
+
368
+ return retval;
369
+ } else {
370
+ return archive;
371
+ }
372
+ }
373
+
374
+ /* */
375
+ static VALUE zipruby_archive_s_open_buffer(int argc, VALUE *argv, VALUE self) {
376
+ VALUE buffer, flags;
377
+ VALUE archive;
378
+ struct zipruby_archive *p_archive;
379
+ void *data = NULL;
380
+ int len = 0, i_flags = 0;
381
+ int errorp;
382
+
383
+ rb_scan_args(argc, argv, "02", &buffer, &flags);
384
+
385
+ if (FIXNUM_P(buffer) && NIL_P(flags)) {
386
+ flags = buffer;
387
+ buffer = Qnil;
388
+ }
389
+
390
+ if (!NIL_P(flags)) {
391
+ i_flags = NUM2INT(flags);
392
+ }
393
+
394
+ if (i_flags & ZIP_CREATE) {
395
+ if (!NIL_P(buffer)) {
396
+ Check_Type(buffer, T_STRING);
397
+ }
398
+
399
+ i_flags = (i_flags | ZIP_TRUNC);
400
+ } else if (TYPE(buffer) == T_STRING) {
401
+ data = RSTRING_PTR(buffer);
402
+ len = RSTRING_LEN(buffer);
403
+ } else if (rb_obj_is_instance_of(buffer, rb_cProc)) {
404
+ data = (void *) buffer;
405
+ len = -1;
406
+ } else {
407
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected String or Proc)", rb_class2name(CLASS_OF(buffer)));
408
+ }
409
+
410
+ archive = rb_funcall(Archive, rb_intern("new"), 0);
411
+ Data_Get_Struct(archive, struct zipruby_archive, p_archive);
412
+
413
+ if ((p_archive->tmpfilnam = zipruby_tmpnam(data, len)) == NULL) {
414
+ rb_raise(Error, "Open archive failed: Failed to create temporary file");
415
+ }
416
+
417
+ if ((p_archive->archive = zip_open(p_archive->tmpfilnam, i_flags, &errorp)) == NULL) {
418
+ char errstr[ERRSTR_BUFSIZE];
419
+ zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
420
+ rb_raise(Error, "Open archive failed: %s", errstr);
421
+ }
422
+
423
+ p_archive->path = rb_str_new2(p_archive->tmpfilnam);
424
+ p_archive->flags = i_flags;
425
+ p_archive->buffer = buffer;
426
+
427
+ if (rb_block_given_p()) {
428
+ VALUE retval;
429
+ int status;
430
+
431
+ retval = rb_protect(rb_yield, archive, &status);
432
+ zipruby_archive_close(archive);
433
+
434
+ if (status != 0) {
435
+ rb_jump_tag(status);
436
+ }
437
+
438
+ return retval;
439
+ } else {
440
+ return archive;
441
+ }
442
+ }
443
+
444
+ /* */
445
+ static VALUE zipruby_archive_s_decrypt(VALUE self, VALUE path, VALUE password) {
446
+ int res;
447
+ int errorp, wrongpwd;
448
+ long pwdlen;
449
+
450
+ Check_Type(path, T_STRING);
451
+ Check_Type(password, T_STRING);
452
+ pwdlen = RSTRING_LEN(password);
453
+
454
+ if (pwdlen < 1) {
455
+ rb_raise(Error, "Decrypt archive failed - %s: Password is empty", RSTRING_PTR(path));
456
+ } else if (pwdlen > 0xff) {
457
+ rb_raise(Error, "Decrypt archive failed - %s: Password is too long", RSTRING_PTR(path));
458
+ }
459
+
460
+ res = zip_decrypt(RSTRING_PTR(path), RSTRING_PTR(password), pwdlen, &errorp, &wrongpwd);
461
+
462
+ if (res == -1) {
463
+ if (wrongpwd) {
464
+ rb_raise(Error, "Decrypt archive failed - %s: Wrong password", RSTRING_PTR(path));
465
+ } else {
466
+ char errstr[ERRSTR_BUFSIZE];
467
+ zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
468
+ rb_raise(Error, "Decrypt archive failed - %s: %s", RSTRING_PTR(path), errstr);
469
+ }
470
+ }
471
+
472
+ return (res > 0) ? Qtrue : Qfalse;
473
+ }
474
+
475
+ /* */
476
+ static VALUE zipruby_archive_s_encrypt(VALUE self, VALUE path, VALUE password) {
477
+ int res;
478
+ int errorp;
479
+ long pwdlen;
480
+
481
+ Check_Type(path, T_STRING);
482
+ Check_Type(password, T_STRING);
483
+ pwdlen = RSTRING_LEN(password);
484
+
485
+ if (pwdlen < 1) {
486
+ rb_raise(Error, "Encrypt archive failed - %s: Password is empty", RSTRING_PTR(path));
487
+ } else if (pwdlen > 0xff) {
488
+ rb_raise(Error, "Encrypt archive failed - %s: Password is too long", RSTRING_PTR(path));
489
+ }
490
+
491
+ res = zip_encrypt(RSTRING_PTR(path), RSTRING_PTR(password), pwdlen, &errorp);
492
+
493
+ if (res == -1) {
494
+ char errstr[ERRSTR_BUFSIZE];
495
+ zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
496
+ rb_raise(Error, "Encrypt archive failed - %s: %s", RSTRING_PTR(path), errstr);
497
+ }
498
+
499
+ return (res > 0) ? Qtrue : Qfalse;
500
+ }
501
+
502
+ /* */
503
+ static VALUE zipruby_archive_close(VALUE self) {
504
+ struct zipruby_archive *p_archive;
505
+ int changed, survivors;
506
+
507
+ if (!zipruby_archive_is_open(self)) {
508
+ return Qfalse;
509
+ }
510
+
511
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
512
+ Check_Archive(p_archive);
513
+
514
+ changed = _zip_changed(p_archive->archive, &survivors);
515
+
516
+ if (zip_close(p_archive->archive) == -1) {
517
+ zip_unchange_all(p_archive->archive);
518
+ zip_unchange_archive(p_archive->archive);
519
+ rb_raise(Error, "Close archive failed: %s", zip_strerror(p_archive->archive));
520
+ }
521
+
522
+ if (!NIL_P(p_archive->buffer) && changed) {
523
+ rb_funcall(p_archive->buffer, rb_intern("replace"), 1, rb_funcall(self, rb_intern("read"), 0));
524
+ }
525
+
526
+ zipruby_rmtmp(p_archive->tmpfilnam);
527
+ p_archive->archive = NULL;
528
+ p_archive->flags = 0;
529
+
530
+ return Qtrue;
531
+ }
532
+
533
+ /* */
534
+ static VALUE zipruby_archive_num_files(VALUE self) {
535
+ struct zipruby_archive *p_archive;
536
+ int num_files;
537
+
538
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
539
+ Check_Archive(p_archive);
540
+ num_files = zip_get_num_files(p_archive->archive);
541
+
542
+ return INT2NUM(num_files);
543
+ }
544
+
545
+ /* */
546
+ static VALUE zipruby_archive_get_name(int argc, VALUE *argv, VALUE self) {
547
+ VALUE index, flags;
548
+ struct zipruby_archive *p_archive;
549
+ int i_flags = 0;
550
+ const char *name;
551
+
552
+ rb_scan_args(argc, argv, "11", &index, &flags);
553
+ Check_Type(index, T_FIXNUM);
554
+
555
+ if (!NIL_P(flags)) {
556
+ i_flags = NUM2INT(flags);
557
+ }
558
+
559
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
560
+ Check_Archive(p_archive);
561
+
562
+ if ((name = zip_get_name(p_archive->archive, NUM2INT(index), i_flags)) == NULL) {
563
+ rb_raise(Error, "Get name failed at %d: %s", index, zip_strerror(p_archive->archive));
564
+ }
565
+
566
+ return (name != NULL) ? rb_str_new2(name) : Qnil;
567
+ }
568
+
569
+ /* */
570
+ static VALUE zipruby_archive_fopen(int argc, VALUE *argv, VALUE self) {
571
+ VALUE index, flags, stat_flags, file;
572
+
573
+ rb_scan_args(argc, argv, "12", &index, &flags, &stat_flags);
574
+ file = rb_funcall(File, rb_intern("new"), 4, self, index, flags, stat_flags);
575
+
576
+ if (rb_block_given_p()) {
577
+ VALUE retval;
578
+ int status;
579
+
580
+ retval = rb_protect(rb_yield, file, &status);
581
+ rb_funcall(file, rb_intern("close"), 0);
582
+
583
+ if (status != 0) {
584
+ rb_jump_tag(status);
585
+ }
586
+
587
+ return retval;
588
+ } else {
589
+ return file;
590
+ }
591
+ }
592
+
593
+ /* */
594
+ static VALUE zipruby_archive_get_stat(int argc, VALUE *argv, VALUE self) {
595
+ VALUE index, flags;
596
+
597
+ rb_scan_args(argc, argv, "11", &index, &flags);
598
+
599
+ return rb_funcall(Stat, rb_intern("new"), 3, self, index, flags);
600
+ }
601
+
602
+ /* */
603
+ static VALUE zipruby_archive_add_buffer(VALUE self, VALUE name, VALUE source) {
604
+ struct zipruby_archive *p_archive;
605
+ struct zip_source *zsource;
606
+ char *data;
607
+ size_t len;
608
+
609
+ Check_Type(name, T_STRING);
610
+ Check_Type(source, T_STRING);
611
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
612
+ Check_Archive(p_archive);
613
+
614
+ len = RSTRING_LEN(source);
615
+
616
+ if ((data = malloc(len)) == NULL) {
617
+ rb_raise(rb_eRuntimeError, "Add file failed: Cannot allocate memory");
618
+ }
619
+
620
+ memset(data, 0, len);
621
+ memcpy(data, RSTRING_PTR(source), len);
622
+
623
+ if ((zsource = zip_source_buffer(p_archive->archive, data, len, 1)) == NULL) {
624
+ free(data);
625
+ rb_raise(Error, "Add file failed - %s: %s", RSTRING_PTR(name), zip_strerror(p_archive->archive));
626
+ }
627
+
628
+ if (zip_add(p_archive->archive, RSTRING_PTR(name), zsource) == -1) {
629
+ zip_source_free(zsource);
630
+ zip_unchange_all(p_archive->archive);
631
+ zip_unchange_archive(p_archive->archive);
632
+ rb_raise(Error, "Add file failed - %s: %s", RSTRING_PTR(name), zip_strerror(p_archive->archive));
633
+ }
634
+
635
+ return Qnil;
636
+ }
637
+
638
+ /* */
639
+ static VALUE zipruby_archive_replace_buffer(int argc, VALUE *argv, VALUE self) {
640
+ struct zipruby_archive *p_archive;
641
+ struct zip_source *zsource;
642
+ VALUE index, source, flags;
643
+ int i_index, i_flags = 0;
644
+ char *data;
645
+ size_t len;
646
+
647
+ rb_scan_args(argc, argv, "21", &index, &source, &flags);
648
+
649
+ if (TYPE(index) != T_STRING && !FIXNUM_P(index)) {
650
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Fixnum or String)", rb_class2name(CLASS_OF(index)));
651
+ }
652
+
653
+ if (!NIL_P(flags)) {
654
+ i_flags = NUM2INT(flags);
655
+ }
656
+
657
+ Check_Type(source, T_STRING);
658
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
659
+ Check_Archive(p_archive);
660
+
661
+ if (FIXNUM_P(index)) {
662
+ i_index = NUM2INT(index);
663
+ } else if ((i_index = zip_name_locate(p_archive->archive, RSTRING_PTR(index), i_flags)) == -1) {
664
+ rb_raise(Error, "Replace file failed - %s: Archive does not contain a file", RSTRING_PTR(index));
665
+ }
666
+
667
+ len = RSTRING_LEN(source);
668
+
669
+ if ((data = malloc(len)) == NULL) {
670
+ rb_raise(rb_eRuntimeError, "Replace file failed: Cannot allocate memory");
671
+ }
672
+
673
+ memcpy(data, RSTRING_PTR(source), len);
674
+
675
+ if ((zsource = zip_source_buffer(p_archive->archive, data, len, 1)) == NULL) {
676
+ free(data);
677
+ rb_raise(Error, "Replace file failed at %d: %s", i_index, zip_strerror(p_archive->archive));
678
+ }
679
+
680
+ if (zip_replace(p_archive->archive, i_index, zsource) == -1) {
681
+ zip_source_free(zsource);
682
+ zip_unchange_all(p_archive->archive);
683
+ zip_unchange_archive(p_archive->archive);
684
+ rb_raise(Error, "Replace file failed at %d: %s", i_index, zip_strerror(p_archive->archive));
685
+ }
686
+
687
+ return Qnil;
688
+ }
689
+
690
+ /* */
691
+ static VALUE zipruby_archive_add_or_replace_buffer(int argc, VALUE *argv, VALUE self) {
692
+ struct zipruby_archive *p_archive;
693
+ VALUE name, source, flags;
694
+ int index, i_flags = 0;
695
+
696
+ rb_scan_args(argc, argv, "21", &name, &source, &flags);
697
+
698
+ if (!NIL_P(flags)) {
699
+ i_flags = NUM2INT(flags);
700
+ }
701
+
702
+ Check_Type(name, T_STRING);
703
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
704
+ Check_Archive(p_archive);
705
+
706
+ index = zip_name_locate(p_archive->archive, RSTRING_PTR(name), i_flags);
707
+
708
+ if (index >= 0) {
709
+ VALUE _args[] = { INT2NUM(index), source };
710
+ return zipruby_archive_replace_buffer(2, _args, self);
711
+ } else {
712
+ return zipruby_archive_add_buffer(self, name, source);
713
+ }
714
+ }
715
+
716
+ /* */
717
+ static VALUE zipruby_archive_add_file(int argc, VALUE *argv, VALUE self) {
718
+ VALUE name, fname;
719
+ struct zipruby_archive *p_archive;
720
+ struct zip_source *zsource;
721
+
722
+ rb_scan_args(argc, argv, "11", &name, &fname);
723
+
724
+ if (NIL_P(fname)) {
725
+ fname = name;
726
+ name = Qnil;
727
+ }
728
+
729
+ Check_Type(fname, T_STRING);
730
+
731
+ if (NIL_P(name)) {
732
+ name = rb_funcall(rb_cFile, rb_intern("basename"), 1, fname);
733
+ }
734
+
735
+ Check_Type(name, T_STRING);
736
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
737
+ Check_Archive(p_archive);
738
+
739
+ if ((zsource = zip_source_file(p_archive->archive, RSTRING_PTR(fname), 0, -1)) == NULL) {
740
+ rb_raise(Error, "Add file failed - %s: %s", RSTRING_PTR(name), zip_strerror(p_archive->archive));
741
+ }
742
+
743
+ if (zip_add(p_archive->archive, RSTRING_PTR(name), zsource) == -1) {
744
+ zip_source_free(zsource);
745
+ zip_unchange_all(p_archive->archive);
746
+ zip_unchange_archive(p_archive->archive);
747
+ rb_raise(Error, "Add file failed - %s: %s", RSTRING_PTR(name), zip_strerror(p_archive->archive));
748
+ }
749
+
750
+ return Qnil;
751
+ }
752
+
753
+ /* */
754
+ static VALUE zipruby_archive_replace_file(int argc, VALUE* argv, VALUE self) {
755
+ struct zipruby_archive *p_archive;
756
+ struct zip_source *zsource;
757
+ VALUE index, fname, flags;
758
+ int i_index, i_flags = 0;
759
+
760
+ rb_scan_args(argc, argv, "21", &index, &fname, &flags);
761
+
762
+ if (TYPE(index) != T_STRING && !FIXNUM_P(index)) {
763
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Fixnum or String)", rb_class2name(CLASS_OF(index)));
764
+ }
765
+
766
+ if (!NIL_P(flags)) {
767
+ i_flags = NUM2INT(flags);
768
+ }
769
+
770
+ Check_Type(fname, T_STRING);
771
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
772
+ Check_Archive(p_archive);
773
+
774
+ if (FIXNUM_P(index)) {
775
+ i_index = NUM2INT(index);
776
+ } else if ((i_index = zip_name_locate(p_archive->archive, RSTRING_PTR(index), i_flags)) == -1) {
777
+ rb_raise(Error, "Replace file failed - %s: Archive does not contain a file", RSTRING_PTR(index));
778
+ }
779
+
780
+ if ((zsource = zip_source_file(p_archive->archive, RSTRING_PTR(fname), 0, -1)) == NULL) {
781
+ rb_raise(Error, "Replace file failed at %d: %s", i_index, zip_strerror(p_archive->archive));
782
+ }
783
+
784
+ if (zip_replace(p_archive->archive, i_index, zsource) == -1) {
785
+ zip_source_free(zsource);
786
+ zip_unchange_all(p_archive->archive);
787
+ zip_unchange_archive(p_archive->archive);
788
+ rb_raise(Error, "Replace file failed at %d: %s", i_index, zip_strerror(p_archive->archive));
789
+ }
790
+
791
+ return Qnil;
792
+ }
793
+
794
+ /* */
795
+ static VALUE zipruby_archive_add_or_replace_file(int argc, VALUE *argv, VALUE self) {
796
+ VALUE name, fname, flags;
797
+ struct zipruby_archive *p_archive;
798
+ int index, i_flags = 0;
799
+
800
+ rb_scan_args(argc, argv, "12", &name, &fname, &flags);
801
+
802
+ if (NIL_P(flags) && FIXNUM_P(fname)) {
803
+ flags = fname;
804
+ fname = Qnil;
805
+ }
806
+
807
+ if (NIL_P(fname)) {
808
+ fname = name;
809
+ name = Qnil;
810
+ }
811
+
812
+ Check_Type(fname, T_STRING);
813
+
814
+ if (NIL_P(name)) {
815
+ name = rb_funcall(rb_cFile, rb_intern("basename"), 1, fname);
816
+ }
817
+
818
+ if (!NIL_P(flags)) {
819
+ i_flags = NUM2INT(flags);
820
+ }
821
+
822
+ Check_Type(name, T_STRING);
823
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
824
+ Check_Archive(p_archive);
825
+
826
+ index = zip_name_locate(p_archive->archive, RSTRING_PTR(name), i_flags);
827
+
828
+ if (index >= 0) {
829
+ VALUE _args[] = { INT2NUM(index), fname };
830
+ return zipruby_archive_replace_file(2, _args, self);
831
+ } else {
832
+ VALUE _args[] = { name, fname };
833
+ return zipruby_archive_add_file(2, _args, self);
834
+ }
835
+ }
836
+
837
+ /* */
838
+ static VALUE zipruby_archive_add_io(VALUE self, VALUE name, VALUE io) {
839
+ VALUE source;
840
+
841
+ Check_IO(io);
842
+ source = rb_funcall(io, rb_intern("read"), 0);
843
+
844
+ return zipruby_archive_add_buffer(self, name, source);
845
+ }
846
+
847
+ /* */
848
+ static VALUE zipruby_archive_replace_io(int argc, VALUE *argv, VALUE self) {
849
+ VALUE source, io, index, flags;
850
+ VALUE _args[3];
851
+
852
+ rb_scan_args(argc, argv, "21", &index, &io, &flags);
853
+ Check_IO(io);
854
+ source = rb_funcall(io, rb_intern("read"), 0);
855
+
856
+ _args[0] = index;
857
+ _args[1] = source;
858
+ _args[2] = flags;
859
+ return zipruby_archive_replace_buffer(2, _args, self);
860
+ }
861
+
862
+ /* */
863
+ static VALUE zipruby_archive_add_or_replace_io(int argc, VALUE *argv, VALUE self) {
864
+ VALUE name, io, flags;
865
+ struct zipruby_archive *p_archive;
866
+ int index, i_flags = 0;
867
+
868
+ rb_scan_args(argc, argv, "21", &name, &io, &flags);
869
+ Check_IO(io);
870
+
871
+ if (!NIL_P(flags)) {
872
+ i_flags = NUM2INT(flags);
873
+ }
874
+
875
+ Check_Type(name, T_STRING);
876
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
877
+ Check_Archive(p_archive);
878
+
879
+ index = zip_name_locate(p_archive->archive, RSTRING_PTR(name), i_flags);
880
+
881
+ if (index >= 0) {
882
+ VALUE _args[] = {INT2NUM(index), io, flags};
883
+ return zipruby_archive_replace_io(2, _args, self);
884
+ } else {
885
+ return zipruby_archive_add_io(self, name, io);
886
+ }
887
+ }
888
+
889
+ /* */
890
+ static VALUE zipruby_archive_add_function(int argc, VALUE *argv, VALUE self) {
891
+ VALUE name, mtime;
892
+ struct zipruby_archive *p_archive;
893
+ struct zip_source *zsource;
894
+ struct read_proc *z;
895
+
896
+ rb_scan_args(argc, argv, "11", &name, &mtime);
897
+ rb_need_block();
898
+ Check_Type(name, T_STRING);
899
+
900
+ if (NIL_P(mtime)) {
901
+ mtime = rb_funcall(rb_cTime, rb_intern("now"), 0);
902
+ } else if (!rb_obj_is_instance_of(mtime, rb_cTime)) {
903
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Time)", rb_class2name(CLASS_OF(mtime)));
904
+ }
905
+
906
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
907
+ Check_Archive(p_archive);
908
+
909
+ if ((z = malloc(sizeof(struct read_proc))) == NULL) {
910
+ zip_unchange_all(p_archive->archive);
911
+ zip_unchange_archive(p_archive->archive);
912
+ rb_raise(rb_eRuntimeError, "Add failed - %s: Cannot allocate memory", RSTRING_PTR(name));
913
+ }
914
+
915
+ z->proc = rb_block_proc();
916
+ z->mtime = mtime;
917
+
918
+ if ((zsource = zip_source_proc(p_archive->archive, z)) == NULL) {
919
+ free(z);
920
+ rb_raise(Error, "Add failed - %s: %s", RSTRING_PTR(name), zip_strerror(p_archive->archive));
921
+ }
922
+
923
+ if (zip_add(p_archive->archive, RSTRING_PTR(name), zsource) == -1) {
924
+ zip_source_free(zsource);
925
+ zip_unchange_all(p_archive->archive);
926
+ zip_unchange_archive(p_archive->archive);
927
+ rb_raise(Error, "Add file failed - %s: %s", RSTRING_PTR(name), zip_strerror(p_archive->archive));
928
+ }
929
+
930
+ return Qnil;
931
+ }
932
+
933
+ /* */
934
+ static VALUE zipruby_archive_replace_function(int argc, VALUE *argv, VALUE self) {
935
+ VALUE index, mtime;
936
+ struct zipruby_archive *p_archive;
937
+ struct zip_source *zsource;
938
+ struct read_proc *z;
939
+
940
+ rb_scan_args(argc, argv, "11", &index, &mtime);
941
+ rb_need_block();
942
+ Check_Type(index, T_FIXNUM);
943
+
944
+ if (NIL_P(mtime)) {
945
+ mtime = rb_funcall(rb_cTime, rb_intern("now"), 0);
946
+ } else if (!rb_obj_is_instance_of(mtime, rb_cTime)) {
947
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Time)", rb_class2name(CLASS_OF(mtime)));
948
+ }
949
+
950
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
951
+ Check_Archive(p_archive);
952
+
953
+ if ((z = malloc(sizeof(struct read_proc))) == NULL) {
954
+ zip_unchange_all(p_archive->archive);
955
+ zip_unchange_archive(p_archive->archive);
956
+ rb_raise(rb_eRuntimeError, "Replace failed at %d: Cannot allocate memory", NUM2INT(index));
957
+ }
958
+
959
+ z->proc = rb_block_proc();
960
+ z->mtime = mtime;
961
+
962
+ if ((zsource = zip_source_proc(p_archive->archive, z)) == NULL) {
963
+ free(z);
964
+ rb_raise(Error, "Replace failed at %d: %s", NUM2INT(index), zip_strerror(p_archive->archive));
965
+ }
966
+
967
+ if (zip_replace(p_archive->archive, NUM2INT(index), zsource) == -1) {
968
+ zip_source_free(zsource);
969
+ zip_unchange_all(p_archive->archive);
970
+ zip_unchange_archive(p_archive->archive);
971
+ rb_raise(Error, "Replace failed at %d: %s", NUM2INT(index), zip_strerror(p_archive->archive));
972
+ }
973
+
974
+ return Qnil;
975
+ }
976
+
977
+ /* */
978
+ static VALUE zipruby_archive_add_or_replace_function(int argc, VALUE *argv, VALUE self) {
979
+ VALUE name, mtime, flags;
980
+ struct zipruby_archive *p_archive;
981
+ int index, i_flags = 0;
982
+
983
+ rb_scan_args(argc, argv, "12", &name, &mtime, &flags);
984
+
985
+ if (NIL_P(flags) && FIXNUM_P(mtime)) {
986
+ flags = mtime;
987
+ mtime = Qnil;
988
+ }
989
+
990
+ if (!NIL_P(flags)) {
991
+ i_flags = NUM2INT(flags);
992
+ }
993
+
994
+ Check_Type(name, T_STRING);
995
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
996
+ Check_Archive(p_archive);
997
+
998
+ index = zip_name_locate(p_archive->archive, RSTRING_PTR(name), i_flags);
999
+
1000
+ if (index >= 0) {
1001
+ VALUE _args[] = { INT2NUM(index), mtime };
1002
+ return zipruby_archive_replace_function(2, _args, self);
1003
+ } else {
1004
+ VALUE _args[] = { name, mtime };
1005
+ return zipruby_archive_add_function(2, _args, self);
1006
+ }
1007
+ }
1008
+
1009
+ /* */
1010
+ static VALUE zipruby_archive_update(int argc, VALUE *argv, VALUE self) {
1011
+ struct zipruby_archive *p_archive, *p_srcarchive;
1012
+ VALUE srcarchive, flags;
1013
+ int i, num_files, i_flags = 0;
1014
+
1015
+ rb_scan_args(argc, argv, "11", &srcarchive, &flags);
1016
+
1017
+ if (!rb_obj_is_instance_of(srcarchive, Archive)) {
1018
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Zip::Archive)", rb_class2name(CLASS_OF(srcarchive)));
1019
+ }
1020
+
1021
+ if (!NIL_P(flags)) {
1022
+ i_flags = NUM2INT(flags);
1023
+ }
1024
+
1025
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1026
+ Check_Archive(p_archive);
1027
+ Data_Get_Struct(srcarchive, struct zipruby_archive, p_srcarchive);
1028
+ Check_Archive(p_srcarchive);
1029
+
1030
+ num_files = zip_get_num_files(p_srcarchive->archive);
1031
+
1032
+ for (i = 0; i < num_files; i++) {
1033
+ struct zip_source *zsource;
1034
+ struct zip_file *fzip;
1035
+ struct zip_stat sb;
1036
+ char *buf;
1037
+ const char *name;
1038
+ int index, error;
1039
+
1040
+ zip_stat_init(&sb);
1041
+
1042
+ if (zip_stat_index(p_srcarchive->archive, i, 0, &sb)) {
1043
+ zip_unchange_all(p_archive->archive);
1044
+ zip_unchange_archive(p_archive->archive);
1045
+ rb_raise(Error, "Update archive failed: %s", zip_strerror(p_srcarchive->archive));
1046
+ }
1047
+
1048
+ if ((buf = malloc(sb.size)) == NULL) {
1049
+ zip_unchange_all(p_archive->archive);
1050
+ zip_unchange_archive(p_archive->archive);
1051
+ rb_raise(rb_eRuntimeError, "Update archive failed: Cannot allocate memory");
1052
+ }
1053
+
1054
+ fzip = zip_fopen_index(p_srcarchive->archive, i, 0);
1055
+
1056
+ if (fzip == NULL) {
1057
+ free(buf);
1058
+ zip_unchange_all(p_archive->archive);
1059
+ zip_unchange_archive(p_archive->archive);
1060
+ rb_raise(Error, "Update archive failed: %s", zip_strerror(p_srcarchive->archive));
1061
+ }
1062
+
1063
+ if (zip_fread(fzip, buf, sb.size) == -1) {
1064
+ free(buf);
1065
+ zip_fclose(fzip);
1066
+ zip_unchange_all(p_archive->archive);
1067
+ zip_unchange_archive(p_archive->archive);
1068
+ rb_raise(Error, "Update archive failed: %s", zip_file_strerror(fzip));
1069
+ }
1070
+
1071
+ if ((error = zip_fclose(fzip)) != 0) {
1072
+ char errstr[ERRSTR_BUFSIZE];
1073
+ free(buf);
1074
+ zip_unchange_all(p_archive->archive);
1075
+ zip_unchange_archive(p_archive->archive);
1076
+ zip_error_to_str(errstr, ERRSTR_BUFSIZE, error, errno);
1077
+ rb_raise(Error, "Update archive failed: %s", errstr);
1078
+ }
1079
+
1080
+ if ((zsource = zip_source_buffer(p_archive->archive, buf, sb.size, 1)) == NULL) {
1081
+ free(buf);
1082
+ zip_unchange_all(p_archive->archive);
1083
+ zip_unchange_archive(p_archive->archive);
1084
+ rb_raise(Error, "Update archive failed: %s", zip_strerror(p_archive->archive));
1085
+ }
1086
+
1087
+ if ((name = zip_get_name(p_srcarchive->archive, i, 0)) == NULL) {
1088
+ zip_source_free(zsource);
1089
+ zip_unchange_all(p_archive->archive);
1090
+ zip_unchange_archive(p_archive->archive);
1091
+ rb_raise(Error, "Update archive failed: %s", zip_strerror(p_srcarchive->archive));
1092
+ }
1093
+
1094
+ index = zip_name_locate(p_archive->archive, name, i_flags);
1095
+
1096
+ if (index >= 0) {
1097
+ if (zip_replace(p_archive->archive, i, zsource) == -1) {
1098
+ zip_source_free(zsource);
1099
+ zip_unchange_all(p_archive->archive);
1100
+ zip_unchange_archive(p_archive->archive);
1101
+ rb_raise(Error, "Update archive failed: %s", zip_strerror(p_archive->archive));
1102
+ }
1103
+ } else {
1104
+ if (zip_add(p_archive->archive, name, zsource) == -1) {
1105
+ zip_source_free(zsource);
1106
+ zip_unchange_all(p_archive->archive);
1107
+ zip_unchange_archive(p_archive->archive);
1108
+ rb_raise(Error, "Update archive failed: %s", zip_strerror(p_archive->archive));
1109
+ }
1110
+ }
1111
+ }
1112
+
1113
+ return Qnil;
1114
+ }
1115
+
1116
+ /* */
1117
+ static VALUE zipruby_archive_get_comment(int argc, VALUE *argv, VALUE self) {
1118
+ VALUE flags;
1119
+ struct zipruby_archive *p_archive;
1120
+ const char *comment;
1121
+ int lenp, i_flags = 0;
1122
+
1123
+ rb_scan_args(argc, argv, "01", &flags);
1124
+
1125
+ if (!NIL_P(flags)) {
1126
+ i_flags = NUM2INT(flags);
1127
+ }
1128
+
1129
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1130
+ Check_Archive(p_archive);
1131
+
1132
+ // XXX: How is the error checked?
1133
+ comment = zip_get_archive_comment(p_archive->archive, &lenp, i_flags);
1134
+
1135
+ return comment ? rb_str_new(comment, lenp) : Qnil;
1136
+ }
1137
+
1138
+ /* */
1139
+ static VALUE zipruby_archive_set_comment(VALUE self, VALUE comment) {
1140
+ struct zipruby_archive *p_archive;
1141
+ const char *s_comment = NULL;
1142
+ int len = 0;
1143
+
1144
+ if (!NIL_P(comment)) {
1145
+ Check_Type(comment, T_STRING);
1146
+ s_comment = RSTRING_PTR(comment);
1147
+ len = RSTRING_LEN(comment);
1148
+ }
1149
+
1150
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1151
+ Check_Archive(p_archive);
1152
+
1153
+ if (zip_set_archive_comment(p_archive->archive, s_comment, len) == -1) {
1154
+ zip_unchange_all(p_archive->archive);
1155
+ zip_unchange_archive(p_archive->archive);
1156
+ rb_raise(Error, "Comment archived failed: %s", zip_strerror(p_archive->archive));
1157
+ }
1158
+
1159
+ return Qnil;
1160
+ }
1161
+
1162
+ /* */
1163
+ static VALUE zipruby_archive_locate_name(int argc, VALUE *argv, VALUE self) {
1164
+ VALUE fname, flags;
1165
+ struct zipruby_archive *p_archive;
1166
+ int i_flags = 0;
1167
+
1168
+ rb_scan_args(argc, argv, "11", &fname, &flags);
1169
+ Check_Type(fname, T_STRING);
1170
+
1171
+ if (!NIL_P(flags)) {
1172
+ i_flags = NUM2INT(flags);
1173
+ }
1174
+
1175
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1176
+ Check_Archive(p_archive);
1177
+
1178
+ return INT2NUM(zip_name_locate(p_archive->archive, RSTRING_PTR(fname), i_flags));
1179
+ }
1180
+
1181
+ /* */
1182
+ static VALUE zipruby_archive_get_fcomment(int argc, VALUE *argv, VALUE self) {
1183
+ VALUE index, flags;
1184
+ struct zipruby_archive *p_archive;
1185
+ const char *comment;
1186
+ int lenp, i_flags = 0;
1187
+
1188
+ rb_scan_args(argc, argv, "11", &index, &flags);
1189
+
1190
+ if (!NIL_P(flags)) {
1191
+ i_flags = NUM2INT(flags);
1192
+ }
1193
+
1194
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1195
+ Check_Archive(p_archive);
1196
+
1197
+ // XXX: How is the error checked?
1198
+ comment = zip_get_file_comment(p_archive->archive, NUM2INT(index), &lenp, i_flags);
1199
+
1200
+ return comment ? rb_str_new(comment, lenp) : Qnil;
1201
+ }
1202
+
1203
+ /* */
1204
+ static VALUE zipruby_archive_set_fcomment(VALUE self, VALUE index, VALUE comment) {
1205
+ struct zipruby_archive *p_archive;
1206
+ char *s_comment = NULL;
1207
+ int len = 0;
1208
+
1209
+ if (!NIL_P(comment)) {
1210
+ Check_Type(comment, T_STRING);
1211
+ s_comment = RSTRING_PTR(comment);
1212
+ len = RSTRING_LEN(comment);
1213
+ }
1214
+
1215
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1216
+ Check_Archive(p_archive);
1217
+
1218
+ if (zip_set_file_comment(p_archive->archive, NUM2INT(index), s_comment, len) == -1) {
1219
+ zip_unchange_all(p_archive->archive);
1220
+ zip_unchange_archive(p_archive->archive);
1221
+ rb_raise(Error, "Comment file failed at %d: %s", NUM2INT(index), zip_strerror(p_archive->archive));
1222
+ }
1223
+
1224
+ return Qnil;
1225
+ }
1226
+
1227
+ /* */
1228
+ static VALUE zipruby_archive_fdelete(VALUE self, VALUE index) {
1229
+ struct zipruby_archive *p_archive;
1230
+
1231
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1232
+ Check_Archive(p_archive);
1233
+
1234
+ if (zip_delete(p_archive->archive, NUM2INT(index)) == -1) {
1235
+ zip_unchange_all(p_archive->archive);
1236
+ zip_unchange_archive(p_archive->archive);
1237
+ rb_raise(Error, "Delete file failed at %d: %s", NUM2INT(index), zip_strerror(p_archive->archive));
1238
+ }
1239
+
1240
+ return Qnil;
1241
+ }
1242
+
1243
+ /* */
1244
+ static VALUE zipruby_archive_frename(VALUE self, VALUE index, VALUE name) {
1245
+ struct zipruby_archive *p_archive;
1246
+
1247
+ Check_Type(name, T_STRING);
1248
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1249
+ Check_Archive(p_archive);
1250
+
1251
+ if (zip_rename(p_archive->archive, NUM2INT(index), RSTRING_PTR(name)) == -1) {
1252
+ zip_unchange_all(p_archive->archive);
1253
+ zip_unchange_archive(p_archive->archive);
1254
+ rb_raise(Error, "Rename file failed at %d: %s", NUM2INT(index), zip_strerror(p_archive->archive));
1255
+ }
1256
+
1257
+ return Qnil;
1258
+ }
1259
+
1260
+ /* */
1261
+ static VALUE zipruby_archive_funchange(VALUE self, VALUE index) {
1262
+ struct zipruby_archive *p_archive;
1263
+
1264
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1265
+ Check_Archive(p_archive);
1266
+
1267
+ if (zip_unchange(p_archive->archive, NUM2INT(index)) == -1) {
1268
+ zip_unchange_all(p_archive->archive);
1269
+ zip_unchange_archive(p_archive->archive);
1270
+ rb_raise(Error, "Unchange file failed at %d: %s", NUM2INT(index), zip_strerror(p_archive->archive));
1271
+ }
1272
+
1273
+ return Qnil;
1274
+ }
1275
+
1276
+ /* */
1277
+ static VALUE zipruby_archive_funchange_all(VALUE self) {
1278
+ struct zipruby_archive *p_archive;
1279
+
1280
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1281
+ Check_Archive(p_archive);
1282
+
1283
+ if (zip_unchange_all(p_archive->archive) == -1) {
1284
+ rb_raise(Error, "Unchange all file failed: %s", zip_strerror(p_archive->archive));
1285
+ }
1286
+
1287
+ return Qnil;
1288
+ }
1289
+
1290
+ /* */
1291
+ static VALUE zipruby_archive_unchange(VALUE self) {
1292
+ struct zipruby_archive *p_archive;
1293
+
1294
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1295
+ Check_Archive(p_archive);
1296
+
1297
+ if (zip_unchange_archive(p_archive->archive) == -1) {
1298
+ rb_raise(Error, "Unchange archive failed: %s", zip_strerror(p_archive->archive));
1299
+ }
1300
+
1301
+ return Qnil;
1302
+ }
1303
+
1304
+ /* */
1305
+ static VALUE zipruby_archive_revert(VALUE self) {
1306
+ zipruby_archive_funchange_all(self);
1307
+ zipruby_archive_unchange(self);
1308
+
1309
+ return Qnil;
1310
+ }
1311
+
1312
+ /* */
1313
+ static VALUE zipruby_archive_each(VALUE self) {
1314
+ struct zipruby_archive *p_archive;
1315
+ int i, num_files;
1316
+
1317
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1318
+ Check_Archive(p_archive);
1319
+ num_files = zip_get_num_files(p_archive->archive);
1320
+
1321
+ for (i = 0; i < num_files; i++) {
1322
+ VALUE file;
1323
+ int status;
1324
+
1325
+ file = rb_funcall(File, rb_intern("new"), 2, self, INT2NUM(i));
1326
+ rb_protect(rb_yield, file, &status);
1327
+ rb_funcall(file, rb_intern("close"), 0);
1328
+
1329
+ if (status != 0) {
1330
+ rb_jump_tag(status);
1331
+ }
1332
+ }
1333
+
1334
+ return Qnil;
1335
+ }
1336
+
1337
+ /* */
1338
+ static VALUE zipruby_archive_commit(VALUE self) {
1339
+ struct zipruby_archive *p_archive;
1340
+ int changed, survivors;
1341
+ int errorp;
1342
+
1343
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1344
+ Check_Archive(p_archive);
1345
+
1346
+ changed = _zip_changed(p_archive->archive, &survivors);
1347
+
1348
+ if (zip_close(p_archive->archive) == -1) {
1349
+ zip_unchange_all(p_archive->archive);
1350
+ zip_unchange_archive(p_archive->archive);
1351
+ rb_raise(Error, "Commit archive failed: %s", zip_strerror(p_archive->archive));
1352
+ }
1353
+
1354
+ if (!NIL_P(p_archive->buffer) && changed) {
1355
+ rb_funcall(p_archive->buffer, rb_intern("replace"), 1, rb_funcall(self, rb_intern("read"), 0));
1356
+ }
1357
+
1358
+ p_archive->archive = NULL;
1359
+ p_archive->flags = (p_archive->flags & ~(ZIP_CREATE | ZIP_EXCL));
1360
+
1361
+ if ((p_archive->archive = zip_open(RSTRING_PTR(p_archive->path), p_archive->flags, &errorp)) == NULL) {
1362
+ char errstr[ERRSTR_BUFSIZE];
1363
+ zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
1364
+ rb_raise(Error, "Commit archive failed: %s", errstr);
1365
+ }
1366
+
1367
+ return Qnil;
1368
+ }
1369
+
1370
+ /* */
1371
+ static VALUE zipruby_archive_is_open(VALUE self) {
1372
+ struct zipruby_archive *p_archive;
1373
+
1374
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1375
+ return (p_archive->archive != NULL) ? Qtrue : Qfalse;
1376
+ }
1377
+
1378
+ /* */
1379
+ static VALUE zipruby_archive_decrypt(VALUE self, VALUE password) {
1380
+ VALUE retval;
1381
+ struct zipruby_archive *p_archive;
1382
+ long pwdlen;
1383
+ int changed, survivors;
1384
+ int errorp;
1385
+
1386
+ Check_Type(password, T_STRING);
1387
+ pwdlen = RSTRING_LEN(password);
1388
+
1389
+ if (pwdlen < 1) {
1390
+ rb_raise(Error, "Decrypt archive failed: Password is empty");
1391
+ } else if (pwdlen > 0xff) {
1392
+ rb_raise(Error, "Decrypt archive failed: Password is too long");
1393
+ }
1394
+
1395
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1396
+ Check_Archive(p_archive);
1397
+
1398
+ changed = _zip_changed(p_archive->archive, &survivors);
1399
+
1400
+ if (zip_close(p_archive->archive) == -1) {
1401
+ zip_unchange_all(p_archive->archive);
1402
+ zip_unchange_archive(p_archive->archive);
1403
+ rb_raise(Error, "Decrypt archive failed: %s", zip_strerror(p_archive->archive));
1404
+ }
1405
+
1406
+ if (!NIL_P(p_archive->buffer) && changed) {
1407
+ rb_funcall(p_archive->buffer, rb_intern("replace"), 1, rb_funcall(self, rb_intern("read"), 0));
1408
+ }
1409
+
1410
+ p_archive->archive = NULL;
1411
+ p_archive->flags = (p_archive->flags & ~(ZIP_CREATE | ZIP_EXCL));
1412
+
1413
+ retval = zipruby_archive_s_decrypt(Archive, p_archive->path, password);
1414
+
1415
+ if ((p_archive->archive = zip_open(RSTRING_PTR(p_archive->path), p_archive->flags, &errorp)) == NULL) {
1416
+ char errstr[ERRSTR_BUFSIZE];
1417
+ zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
1418
+ rb_raise(Error, "Decrypt archive failed: %s", errstr);
1419
+ }
1420
+
1421
+ return retval;
1422
+ }
1423
+
1424
+ /* */
1425
+ static VALUE zipruby_archive_encrypt(VALUE self, VALUE password) {
1426
+ VALUE retval;
1427
+ struct zipruby_archive *p_archive;
1428
+ long pwdlen;
1429
+ int changed, survivors;
1430
+ int errorp;
1431
+
1432
+ Check_Type(password, T_STRING);
1433
+ pwdlen = RSTRING_LEN(password);
1434
+
1435
+ if (pwdlen < 1) {
1436
+ rb_raise(Error, "Encrypt archive failed: Password is empty");
1437
+ } else if (pwdlen > 0xff) {
1438
+ rb_raise(Error, "Encrypt archive failed: Password is too long");
1439
+ }
1440
+
1441
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1442
+ Check_Archive(p_archive);
1443
+
1444
+ changed = _zip_changed(p_archive->archive, &survivors);
1445
+
1446
+ if (zip_close(p_archive->archive) == -1) {
1447
+ zip_unchange_all(p_archive->archive);
1448
+ zip_unchange_archive(p_archive->archive);
1449
+ rb_raise(Error, "Encrypt archive failed: %s", zip_strerror(p_archive->archive));
1450
+ }
1451
+
1452
+ if (!NIL_P(p_archive->buffer) && changed) {
1453
+ rb_funcall(p_archive->buffer, rb_intern("replace"), 1, rb_funcall(self, rb_intern("read"), 0));
1454
+ }
1455
+
1456
+ p_archive->archive = NULL;
1457
+ p_archive->flags = (p_archive->flags & ~(ZIP_CREATE | ZIP_EXCL));
1458
+
1459
+ retval = zipruby_archive_s_encrypt(Archive, p_archive->path, password);
1460
+
1461
+ if ((p_archive->archive = zip_open(RSTRING_PTR(p_archive->path), p_archive->flags, &errorp)) == NULL) {
1462
+ char errstr[ERRSTR_BUFSIZE];
1463
+ zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
1464
+ rb_raise(Error, "Encrypt archive failed: %s", errstr);
1465
+ }
1466
+
1467
+ return retval;
1468
+ }
1469
+
1470
+ /* */
1471
+ static VALUE zipruby_archive_read(VALUE self) {
1472
+ VALUE retval = Qnil;
1473
+ struct zipruby_archive *p_archive;
1474
+ FILE *fzip;
1475
+ char buf[DATA_BUFSIZE];
1476
+ ssize_t n;
1477
+ int block_given;
1478
+
1479
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1480
+
1481
+ if (NIL_P(p_archive->path)) {
1482
+ rb_raise(rb_eRuntimeError, "invalid Zip::Archive");
1483
+ }
1484
+
1485
+ #ifdef _WIN32
1486
+ if (fopen_s(&fzip, RSTRING_PTR(p_archive->path), "rb") != 0) {
1487
+ rb_raise(Error, "Read archive failed: Cannot open archive");
1488
+ }
1489
+ #else
1490
+ if ((fzip = fopen(RSTRING_PTR(p_archive->path), "rb")) == NULL) {
1491
+ rb_raise(Error, "Read archive failed: Cannot open archive");
1492
+ }
1493
+ #endif
1494
+
1495
+ block_given = rb_block_given_p();
1496
+
1497
+ while ((n = fread(buf, 1, sizeof(buf), fzip)) > 0) {
1498
+ if (block_given) {
1499
+ rb_yield(rb_str_new(buf, n));
1500
+ } else {
1501
+ if (NIL_P(retval)) {
1502
+ retval = rb_str_new(buf, n);
1503
+ } else {
1504
+ rb_str_buf_cat(retval, buf, n);
1505
+ }
1506
+ }
1507
+ }
1508
+
1509
+ #if defined(RUBY_VM) && defined(_WIN32)
1510
+ _fclose_nolock(fzip);
1511
+ #elif defined(RUBY_WIN32_H)
1512
+ #undef fclose
1513
+ fclose(fzip);
1514
+ #define fclose(f) rb_w32_fclose(f)
1515
+ #else
1516
+ fclose(fzip);
1517
+ #endif
1518
+
1519
+ if (n == -1) {
1520
+ rb_raise(Error, "Read archive failed");
1521
+ }
1522
+
1523
+ return retval;
1524
+ }
1525
+ #include "zipruby.h"
1526
+ #include "zipruby_error.h"
1527
+ #include "ruby.h"
1528
+
1529
+ extern VALUE Zip;
1530
+ VALUE Error;
1531
+
1532
+ void Init_zipruby_error() {
1533
+ Error = rb_define_class_under(Zip, "Error", rb_eStandardError);
1534
+ }
1535
+ #include <errno.h>
1536
+
1537
+ #include "zip.h"
1538
+ #include "zipint.h"
1539
+ #include "zipruby.h"
1540
+ #include "zipruby_archive.h"
1541
+ #include "zipruby_file.h"
1542
+ #include "zipruby_stat.h"
1543
+ #include "ruby.h"
1544
+
1545
+ #define MIN(a, b) ((a) < (b) ? (a) : (b))
1546
+
1547
+ static VALUE zipruby_file(VALUE klass);
1548
+ static VALUE zipruby_file_alloc(VALUE klass);
1549
+ static void zipruby_file_mark(struct zipruby_file *p);
1550
+ static void zipruby_file_free(struct zipruby_file *p);
1551
+ static VALUE zipruby_file_initialize(int argc, VALUE *argv, VALUE self);
1552
+ static VALUE zipruby_file_close(VALUE self);
1553
+ static VALUE zipruby_file_read(int argc, VALUE *argv, VALUE self);
1554
+ static VALUE zipruby_file_stat(VALUE self);
1555
+ static VALUE zipruby_file_get_comment(int argc, VALUE *argv, VALUE self);
1556
+ static VALUE zipruby_file_set_comment(VALUE self, VALUE comment);
1557
+ static VALUE zipruby_file_delete(VALUE self);
1558
+ static VALUE zipruby_file_rename(VALUE self, VALUE name);
1559
+ static VALUE zipruby_file_unchange(VALUE self);
1560
+ static VALUE zipruby_file_name(VALUE self);
1561
+ static VALUE zipruby_file_index(VALUE self);
1562
+ static VALUE zipruby_file_crc(VALUE self);
1563
+ static VALUE zipruby_file_size(VALUE self);
1564
+ static VALUE zipruby_file_mtime(VALUE self);
1565
+ static VALUE zipruby_file_comp_size(VALUE self);
1566
+ static VALUE zipruby_file_comp_method(VALUE self);
1567
+ static VALUE zipruby_file_encryption_method(VALUE self);
1568
+
1569
+ extern VALUE Zip;
1570
+ extern VALUE Archive;
1571
+ VALUE File;
1572
+ extern VALUE Stat;
1573
+ extern VALUE Error;
1574
+
1575
+ void Init_zipruby_file() {
1576
+ File = rb_define_class_under(Zip, "File", rb_cObject);
1577
+ rb_define_alloc_func(File, zipruby_file_alloc);
1578
+ rb_define_method(File, "initialize", zipruby_file_initialize, -1);
1579
+ rb_define_method(File, "close", zipruby_file_close, 0);
1580
+ rb_define_method(File, "read", zipruby_file_read, -1);
1581
+ rb_define_method(File, "stat", zipruby_file_stat, 0);
1582
+ rb_define_method(File, "get_comment", zipruby_file_get_comment, -1);
1583
+ rb_define_method(File, "comment", zipruby_file_get_comment, -1);
1584
+ rb_define_method(File, "comment=", zipruby_file_set_comment, 1);
1585
+ rb_define_method(File, "delete", zipruby_file_delete, 0);
1586
+ rb_define_method(File, "rename", zipruby_file_rename, 1);
1587
+ rb_define_method(File, "unchange", zipruby_file_unchange, 1);
1588
+ rb_define_method(File, "revert", zipruby_file_unchange, 1);
1589
+ rb_define_method(File, "name", zipruby_file_name, 0);
1590
+ rb_define_method(File, "index", zipruby_file_index, 0);
1591
+ rb_define_method(File, "crc", zipruby_file_crc, 0);
1592
+ rb_define_method(File, "size", zipruby_file_size, 0);
1593
+ rb_define_method(File, "mtime", zipruby_file_mtime, 0);
1594
+ rb_define_method(File, "comp_size", zipruby_file_comp_size, 0);
1595
+ rb_define_method(File, "comp_method", zipruby_file_comp_method, 0);
1596
+ rb_define_method(File, "encryption_method", zipruby_file_encryption_method, 0);
1597
+ }
1598
+
1599
+ static VALUE zipruby_file_alloc(VALUE klass) {
1600
+ struct zipruby_file *p = ALLOC(struct zipruby_file);
1601
+
1602
+ p->archive = NULL;
1603
+ p->file = NULL;
1604
+ p->sb = NULL;
1605
+
1606
+ return Data_Wrap_Struct(klass, zipruby_file_mark, zipruby_file_free, p);
1607
+ }
1608
+
1609
+ static void zipruby_file_mark(struct zipruby_file *p) {
1610
+ if (p->archive) { rb_gc_mark(p->v_archive); }
1611
+ if (p->sb) { rb_gc_mark(p->v_sb); }
1612
+ }
1613
+
1614
+ static void zipruby_file_free(struct zipruby_file *p) {
1615
+ xfree(p);
1616
+ }
1617
+
1618
+ /* */
1619
+ static VALUE zipruby_file_initialize(int argc, VALUE *argv, VALUE self) {
1620
+ VALUE archive, index, flags, stat_flags;
1621
+ struct zipruby_archive *p_archive;
1622
+ struct zipruby_file *p_file;
1623
+ struct zipruby_stat *p_stat;
1624
+ struct zip_file *fzip;
1625
+ char *fname = NULL;
1626
+ int i_index = -1, i_flags = 0;
1627
+
1628
+ rb_scan_args(argc, argv, "22", &archive, &index, &flags, &stat_flags);
1629
+
1630
+ if (!rb_obj_is_instance_of(archive, Archive)) {
1631
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Zip::Archive)", rb_class2name(CLASS_OF(archive)));
1632
+ }
1633
+
1634
+ switch (TYPE(index)) {
1635
+ case T_STRING: fname = RSTRING_PTR(index); break;
1636
+ case T_FIXNUM: i_index = NUM2INT(index); break;
1637
+ default:
1638
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected String or Fixnum)", rb_class2name(CLASS_OF(index)));
1639
+ }
1640
+
1641
+ if (!NIL_P(flags)) {
1642
+ i_flags = NUM2INT(flags);
1643
+ }
1644
+
1645
+ Data_Get_Struct(archive, struct zipruby_archive, p_archive);
1646
+ Check_Archive(p_archive);
1647
+
1648
+ if (fname) {
1649
+ fzip = zip_fopen(p_archive->archive, fname, i_flags);
1650
+
1651
+ if (fzip == NULL) {
1652
+ rb_raise(Error, "Open file failed - %s: %s", fname, zip_strerror(p_archive->archive));
1653
+ }
1654
+ } else {
1655
+ fzip = zip_fopen_index(p_archive->archive, i_index, i_flags);
1656
+
1657
+ if (fzip == NULL) {
1658
+ rb_raise(Error, "Open file failed at %d: %s", i_index, zip_strerror(p_archive->archive));
1659
+ }
1660
+ }
1661
+
1662
+ Data_Get_Struct(self, struct zipruby_file, p_file);
1663
+ p_file->v_archive = archive;
1664
+ p_file->archive = p_archive->archive;
1665
+ p_file->file = fzip;
1666
+ p_file->v_sb = rb_funcall(Stat, rb_intern("new"), 3, archive, index, stat_flags);
1667
+ Data_Get_Struct(p_file->v_sb, struct zipruby_stat, p_stat);
1668
+ p_file->sb = p_stat->sb;
1669
+
1670
+ return Qnil;
1671
+ }
1672
+
1673
+ /* */
1674
+ static VALUE zipruby_file_close(VALUE self) {
1675
+ struct zipruby_file *p_file;
1676
+ int error;
1677
+
1678
+ Data_Get_Struct(self, struct zipruby_file, p_file);
1679
+ Check_File(p_file);
1680
+
1681
+ if ((error = zip_fclose(p_file->file)) != 0) {
1682
+ char errstr[ERRSTR_BUFSIZE];
1683
+ zip_unchange(p_file->archive, p_file->sb->index);
1684
+ zip_error_to_str(errstr, ERRSTR_BUFSIZE, error, errno);
1685
+ rb_raise(Error, "Close file failed: %s", errstr);
1686
+ }
1687
+
1688
+ p_file->archive = NULL;
1689
+ p_file->file = NULL;
1690
+ p_file->sb = NULL;
1691
+
1692
+ return Qnil;
1693
+ }
1694
+
1695
+ /* */
1696
+ static VALUE zipruby_file_read(int argc, VALUE *argv, VALUE self) {
1697
+ VALUE size, retval = Qnil;
1698
+ struct zipruby_file *p_file;
1699
+ struct zip_stat sb;
1700
+ int block_given;
1701
+ size_t bytes_left;
1702
+ char buf[DATA_BUFSIZE];
1703
+ ssize_t n;
1704
+
1705
+ rb_scan_args(argc, argv, "01", &size);
1706
+ Data_Get_Struct(self, struct zipruby_file, p_file);
1707
+ Check_File(p_file);
1708
+ zip_stat_init(&sb);
1709
+
1710
+ if (p_file->archive->cdir->entry[0].bitflags & ZIP_GPBF_ENCRYPTED) {
1711
+ rb_raise(Error, "Read file failed: File encrypted");
1712
+ }
1713
+
1714
+ if (zip_stat_index(p_file->archive, p_file->sb->index, 0, &sb)) {
1715
+ rb_raise(Error, "Read file failed: %s", zip_strerror(p_file->archive));
1716
+ }
1717
+
1718
+ if (NIL_P(size)) {
1719
+ bytes_left = sb.size;
1720
+ } else {
1721
+ bytes_left = NUM2LONG(size);
1722
+ }
1723
+
1724
+ if (bytes_left <= 0) {
1725
+ return Qnil;
1726
+ }
1727
+
1728
+ block_given = rb_block_given_p();
1729
+
1730
+ while ((n = zip_fread(p_file->file, buf, MIN(bytes_left, sizeof(buf)))) > 0) {
1731
+ if (block_given) {
1732
+ rb_yield(rb_str_new(buf, n));
1733
+ } else {
1734
+ if (NIL_P(retval)) {
1735
+ retval = rb_str_new(buf, n);
1736
+ } else {
1737
+ rb_str_buf_cat(retval, buf, n);
1738
+ }
1739
+ }
1740
+
1741
+ bytes_left -= n;
1742
+ }
1743
+
1744
+ if (n == -1) {
1745
+ rb_raise(Error, "Read file failed: %s", zip_file_strerror(p_file->file));
1746
+ }
1747
+
1748
+ return retval;
1749
+ }
1750
+
1751
+ /* */
1752
+ static VALUE zipruby_file_stat(VALUE self) {
1753
+ struct zipruby_file *p_file;
1754
+
1755
+ Data_Get_Struct(self, struct zipruby_file, p_file);
1756
+ Check_File(p_file);
1757
+
1758
+ return p_file->v_sb;
1759
+ }
1760
+
1761
+ /* */
1762
+ static VALUE zipruby_file_get_comment(int argc, VALUE *argv, VALUE self) {
1763
+ VALUE flags;
1764
+ struct zipruby_file *p_file;
1765
+ const char *comment;
1766
+ int lenp, i_flags = 0;
1767
+
1768
+ rb_scan_args(argc, argv, "01", &flags);
1769
+
1770
+ if (!NIL_P(flags)) {
1771
+ i_flags = NUM2INT(flags);
1772
+ }
1773
+
1774
+ Data_Get_Struct(self, struct zipruby_file, p_file);
1775
+ Check_File(p_file);
1776
+
1777
+ // XXX: How is the error checked?
1778
+ comment = zip_get_file_comment(p_file->archive, p_file->sb->index, &lenp, i_flags);
1779
+
1780
+ return comment ? rb_str_new(comment, lenp) : Qnil;
1781
+ }
1782
+
1783
+ /* */
1784
+ static VALUE zipruby_file_set_comment(VALUE self, VALUE comment) {
1785
+ struct zipruby_file *p_file;
1786
+ char *s_comment = NULL;
1787
+ int len = 0;
1788
+
1789
+ if (!NIL_P(comment)) {
1790
+ Check_Type(comment, T_STRING);
1791
+ s_comment = RSTRING_PTR(comment);
1792
+ len = RSTRING_LEN(comment);
1793
+ }
1794
+
1795
+ Data_Get_Struct(self, struct zipruby_file, p_file);
1796
+ Check_File(p_file);
1797
+
1798
+ if (zip_set_file_comment(p_file->archive, p_file->sb->index, s_comment, len) == -1) {
1799
+ zip_unchange_all(p_file->archive);
1800
+ zip_unchange_archive(p_file->archive);
1801
+ rb_raise(Error, "Comment file failed - %s: %s", p_file->sb->name, zip_strerror(p_file->archive));
1802
+ }
1803
+
1804
+ return Qnil;
1805
+ }
1806
+
1807
+ /* */
1808
+ static VALUE zipruby_file_delete(VALUE self) {
1809
+ struct zipruby_file *p_file;
1810
+
1811
+ Data_Get_Struct(self, struct zipruby_file, p_file);
1812
+ Check_File(p_file);
1813
+
1814
+ if (zip_delete(p_file->archive, p_file->sb->index) == -1) {
1815
+ zip_unchange_all(p_file->archive);
1816
+ zip_unchange_archive(p_file->archive);
1817
+ rb_raise(Error, "Delete file failed - %s: %s", p_file->sb->name, zip_strerror(p_file->archive));
1818
+ }
1819
+
1820
+ return Qnil;
1821
+ }
1822
+
1823
+ /* */
1824
+ static VALUE zipruby_file_rename(VALUE self, VALUE name) {
1825
+ struct zipruby_file *p_file;
1826
+
1827
+ Check_Type(name, T_STRING);
1828
+ Data_Get_Struct(self, struct zipruby_file, p_file);
1829
+ Check_File(p_file);
1830
+
1831
+ if (zip_rename(p_file->archive, p_file->sb->index, RSTRING_PTR(name)) == -1) {
1832
+ zip_unchange_all(p_file->archive);
1833
+ zip_unchange_archive(p_file->archive);
1834
+ rb_raise(Error, "Rename file failed - %s: %s", p_file->sb->name, zip_strerror(p_file->archive));
1835
+ }
1836
+
1837
+ return Qnil;
1838
+ }
1839
+
1840
+ /* */
1841
+ static VALUE zipruby_file_unchange(VALUE self) {
1842
+ struct zipruby_file *p_file;
1843
+
1844
+ Data_Get_Struct(self, struct zipruby_file, p_file);
1845
+ Check_File(p_file);
1846
+
1847
+ if (zip_unchange(p_file->archive, p_file->sb->index) == -1) {
1848
+ rb_raise(Error, "Unchange file failed - %s: %s", p_file->sb->name, zip_strerror(p_file->archive));
1849
+ }
1850
+
1851
+ return Qnil;
1852
+ }
1853
+
1854
+ /* */
1855
+ static VALUE zipruby_file_name(VALUE self) {
1856
+ struct zipruby_file *p_file;
1857
+
1858
+ Data_Get_Struct(self, struct zipruby_file, p_file);
1859
+ Check_File(p_file);
1860
+
1861
+ return rb_funcall(p_file->v_sb, rb_intern("name"), 0);
1862
+ }
1863
+
1864
+ /* */
1865
+ static VALUE zipruby_file_index(VALUE self) {
1866
+ struct zipruby_file *p_file;
1867
+
1868
+ Data_Get_Struct(self, struct zipruby_file, p_file);
1869
+ Check_File(p_file);
1870
+
1871
+ return rb_funcall(p_file->v_sb, rb_intern("index"), 0);
1872
+ }
1873
+
1874
+ /* */
1875
+ static VALUE zipruby_file_crc(VALUE self) {
1876
+ struct zipruby_file *p_file;
1877
+
1878
+ Data_Get_Struct(self, struct zipruby_file, p_file);
1879
+ Check_File(p_file);
1880
+
1881
+ return rb_funcall(p_file->v_sb, rb_intern("crc"), 0);
1882
+ }
1883
+
1884
+ /* */
1885
+ static VALUE zipruby_file_size(VALUE self) {
1886
+ struct zipruby_file *p_file;
1887
+
1888
+ Data_Get_Struct(self, struct zipruby_file, p_file);
1889
+ Check_File(p_file);
1890
+
1891
+ return rb_funcall(p_file->v_sb, rb_intern("size"), 0);
1892
+ }
1893
+
1894
+ /* */
1895
+ static VALUE zipruby_file_mtime(VALUE self) {
1896
+ struct zipruby_file *p_file;
1897
+
1898
+ Data_Get_Struct(self, struct zipruby_file, p_file);
1899
+ Check_File(p_file);
1900
+
1901
+ return rb_funcall(p_file->v_sb, rb_intern("mtime"), 0);
1902
+ }
1903
+
1904
+ /* */
1905
+ static VALUE zipruby_file_comp_size(VALUE self) {
1906
+ struct zipruby_file *p_file;
1907
+
1908
+ Data_Get_Struct(self, struct zipruby_file, p_file);
1909
+ Check_File(p_file);
1910
+
1911
+ return rb_funcall(p_file->v_sb, rb_intern("comp_size"), 0);
1912
+ }
1913
+
1914
+ /* */
1915
+ static VALUE zipruby_file_comp_method(VALUE self) {
1916
+ struct zipruby_file *p_file;
1917
+
1918
+ Data_Get_Struct(self, struct zipruby_file, p_file);
1919
+ Check_File(p_file);
1920
+
1921
+ return rb_funcall(p_file->v_sb, rb_intern("comp_method"), 0);
1922
+ }
1923
+
1924
+ /* */
1925
+ static VALUE zipruby_file_encryption_method(VALUE self) {
1926
+ struct zipruby_file *p_file;
1927
+
1928
+ Data_Get_Struct(self, struct zipruby_file, p_file);
1929
+ Check_File(p_file);
1930
+
1931
+ return rb_funcall(p_file->v_sb, rb_intern("encryption_method"), 0);
1932
+ }
1933
+ #include "zip.h"
1934
+ #include "zipruby.h"
1935
+ #include "zipruby_archive.h"
1936
+ #include "zipruby_stat.h"
1937
+ #include "ruby.h"
1938
+
1939
+ static VALUE zipruby_stat_alloc(VALUE klass);
1940
+ static void zipruby_stat_free(struct zipruby_stat *p);
1941
+ static VALUE zipruby_stat_initialize(int argc, VALUE *argv, VALUE self);
1942
+ static VALUE zipruby_stat_name(VALUE self);
1943
+ static VALUE zipruby_stat_index(VALUE self);
1944
+ static VALUE zipruby_stat_crc(VALUE self);
1945
+ static VALUE zipruby_stat_size(VALUE self);
1946
+ static VALUE zipruby_stat_mtime(VALUE self);
1947
+ static VALUE zipruby_stat_comp_size(VALUE self);
1948
+ static VALUE zipruby_stat_comp_method(VALUE self);
1949
+ static VALUE zipruby_stat_encryption_method(VALUE self);
1950
+
1951
+ extern VALUE Zip;
1952
+ extern VALUE Archive;
1953
+ VALUE Stat;
1954
+ extern VALUE Error;
1955
+
1956
+ void Init_zipruby_stat() {
1957
+ Stat = rb_define_class_under(Zip, "Stat", rb_cObject);
1958
+ rb_define_alloc_func(Stat, zipruby_stat_alloc);
1959
+ rb_define_method(Stat, "initialize", zipruby_stat_initialize, -1);
1960
+ rb_define_method(Stat, "name", zipruby_stat_name, 0);
1961
+ rb_define_method(Stat, "index", zipruby_stat_index, 0);
1962
+ rb_define_method(Stat, "crc", zipruby_stat_crc, 0);
1963
+ rb_define_method(Stat, "size", zipruby_stat_size, 0);
1964
+ rb_define_method(Stat, "mtime", zipruby_stat_mtime, 0);
1965
+ rb_define_method(Stat, "comp_size", zipruby_stat_comp_size, 0);
1966
+ rb_define_method(Stat, "comp_method", zipruby_stat_comp_method, 0);
1967
+ rb_define_method(Stat, "encryption_method", zipruby_stat_encryption_method, 0);
1968
+ }
1969
+
1970
+ static VALUE zipruby_stat_alloc(VALUE klass) {
1971
+ struct zipruby_stat *p = ALLOC(struct zipruby_stat);
1972
+
1973
+ p->sb = ALLOC(struct zip_stat);
1974
+ zip_stat_init(p->sb);
1975
+
1976
+ return Data_Wrap_Struct(klass, 0, zipruby_stat_free, p);
1977
+ }
1978
+
1979
+ static void zipruby_stat_free(struct zipruby_stat *p) {
1980
+ xfree(p->sb);
1981
+ xfree(p);
1982
+ }
1983
+
1984
+ /* */
1985
+ static VALUE zipruby_stat_initialize(int argc, VALUE *argv, VALUE self) {
1986
+ VALUE archive, index, flags;
1987
+ struct zipruby_archive *p_archive;
1988
+ struct zipruby_stat *p_stat;
1989
+ char *fname = NULL;
1990
+ int i_index = -1, i_flags = 0;
1991
+
1992
+ rb_scan_args(argc, argv, "21", &archive, &index, &flags);
1993
+
1994
+ if (!rb_obj_is_instance_of(archive, Archive)) {
1995
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Zip::Archive)", rb_class2name(CLASS_OF(archive)));
1996
+ }
1997
+
1998
+ switch (TYPE(index)) {
1999
+ case T_STRING: fname = RSTRING_PTR(index); break;
2000
+ case T_FIXNUM: i_index = NUM2INT(index); break;
2001
+ default:
2002
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected String or Fixnum)", rb_class2name(CLASS_OF(index)));
2003
+ }
2004
+
2005
+ if (!NIL_P(flags)) {
2006
+ i_flags = NUM2INT(flags);
2007
+ }
2008
+
2009
+ Data_Get_Struct(archive, struct zipruby_archive, p_archive);
2010
+ Check_Archive(p_archive);
2011
+ Data_Get_Struct(self, struct zipruby_stat, p_stat);
2012
+
2013
+ if (fname) {
2014
+ if (zip_stat(p_archive->archive, fname, i_flags, p_stat->sb) != 0) {
2015
+ rb_raise(Error, "Obtain file status failed - %s: %s", fname, zip_strerror(p_archive->archive));
2016
+ }
2017
+ } else {
2018
+ if (zip_stat_index(p_archive->archive, i_index, i_flags, p_stat->sb) != 0) {
2019
+ rb_raise(Error, "Obtain file status failed at %d: %s", i_index, zip_strerror(p_archive->archive));
2020
+ }
2021
+ }
2022
+
2023
+ return Qnil;
2024
+ }
2025
+
2026
+ /* */
2027
+ static VALUE zipruby_stat_name(VALUE self) {
2028
+ struct zipruby_stat *p_stat;
2029
+
2030
+ Data_Get_Struct(self, struct zipruby_stat, p_stat);
2031
+
2032
+ return p_stat->sb->name ? rb_str_new2(p_stat->sb->name) : Qnil;
2033
+ }
2034
+
2035
+ /* */
2036
+ static VALUE zipruby_stat_index(VALUE self) {
2037
+ struct zipruby_stat *p_stat;
2038
+
2039
+ Data_Get_Struct(self, struct zipruby_stat, p_stat);
2040
+
2041
+ return INT2NUM(p_stat->sb->index);
2042
+ }
2043
+
2044
+ /* */
2045
+ static VALUE zipruby_stat_crc(VALUE self) {
2046
+ struct zipruby_stat *p_stat;
2047
+
2048
+ Data_Get_Struct(self, struct zipruby_stat, p_stat);
2049
+
2050
+ return UINT2NUM(p_stat->sb->crc);
2051
+ }
2052
+
2053
+ /* */
2054
+ static VALUE zipruby_stat_size(VALUE self) {
2055
+ struct zipruby_stat *p_stat;
2056
+
2057
+ Data_Get_Struct(self, struct zipruby_stat, p_stat);
2058
+
2059
+ return LONG2NUM(p_stat->sb->size);
2060
+ }
2061
+
2062
+ /* */
2063
+ static VALUE zipruby_stat_mtime(VALUE self) {
2064
+ struct zipruby_stat *p_stat;
2065
+
2066
+ Data_Get_Struct(self, struct zipruby_stat, p_stat);
2067
+
2068
+ return rb_funcall(rb_cTime, rb_intern("at"), 1, LONG2NUM((long) p_stat->sb->mtime));
2069
+ }
2070
+
2071
+ /* */
2072
+ static VALUE zipruby_stat_comp_size(VALUE self) {
2073
+ struct zipruby_stat *p_stat;
2074
+
2075
+ Data_Get_Struct(self, struct zipruby_stat, p_stat);
2076
+
2077
+ return LONG2NUM(p_stat->sb->comp_size);
2078
+ }
2079
+
2080
+ /* */
2081
+ static VALUE zipruby_stat_comp_method(VALUE self) {
2082
+ struct zipruby_stat *p_stat;
2083
+
2084
+ Data_Get_Struct(self, struct zipruby_stat, p_stat);
2085
+
2086
+ return INT2NUM(p_stat->sb->comp_method);
2087
+ }
2088
+
2089
+ /* */
2090
+ static VALUE zipruby_stat_encryption_method(VALUE self) {
2091
+ struct zipruby_stat *p_stat;
2092
+
2093
+ Data_Get_Struct(self, struct zipruby_stat, p_stat);
2094
+
2095
+ return INT2NUM(p_stat->sb->encryption_method);
2096
+ }
2097
+ #include "ruby.h"
2098
+ #include "zip.h"
2099
+ #include "zipruby.h"
2100
+ #include "zipruby_zip.h"
2101
+
2102
+ VALUE Zip;
2103
+
2104
+ void Init_zipruby_zip() {
2105
+ Zip = rb_define_module("Zip");
2106
+ rb_define_const(Zip, "VERSION", rb_str_new2(VERSION));
2107
+
2108
+ rb_define_const(Zip, "CREATE", INT2NUM(ZIP_CREATE));
2109
+ rb_define_const(Zip, "EXCL", INT2NUM(ZIP_EXCL));
2110
+ rb_define_const(Zip, "CHECKCONS", INT2NUM(ZIP_CHECKCONS));
2111
+ rb_define_const(Zip, "TRUNC", INT2NUM(ZIP_TRUNC));
2112
+
2113
+ rb_define_const(Zip, "FL_NOCASE", INT2NUM(ZIP_FL_NOCASE));
2114
+ rb_define_const(Zip, "FL_NODIR", INT2NUM(ZIP_FL_NODIR));
2115
+ rb_define_const(Zip, "FL_COMPRESSED", INT2NUM(ZIP_FL_COMPRESSED));
2116
+ rb_define_const(Zip, "FL_UNCHANGED", INT2NUM(ZIP_FL_UNCHANGED));
2117
+
2118
+ rb_define_const(Zip, "CM_DEFAULT" , INT2NUM(ZIP_CM_DEFAULT));
2119
+ rb_define_const(Zip, "CM_STORE", INT2NUM(ZIP_CM_STORE));
2120
+ rb_define_const(Zip, "CM_SHRINK", INT2NUM(ZIP_CM_SHRINK));
2121
+ rb_define_const(Zip, "CM_REDUCE_1", INT2NUM(ZIP_CM_REDUCE_1));
2122
+ rb_define_const(Zip, "CM_REDUCE_2", INT2NUM(ZIP_CM_REDUCE_2));
2123
+ rb_define_const(Zip, "CM_REDUCE_3", INT2NUM(ZIP_CM_REDUCE_3));
2124
+ rb_define_const(Zip, "CM_REDUCE_4", INT2NUM(ZIP_CM_REDUCE_4));
2125
+ rb_define_const(Zip, "CM_IMPLODE", INT2NUM(ZIP_CM_IMPLODE));
2126
+ rb_define_const(Zip, "CM_DEFLATE", INT2NUM(ZIP_CM_DEFLATE));
2127
+ rb_define_const(Zip, "CM_DEFLATE64", INT2NUM(ZIP_CM_DEFLATE64));
2128
+ rb_define_const(Zip, "CM_PKWARE_IMPLODE", INT2NUM(ZIP_CM_PKWARE_IMPLODE));
2129
+ rb_define_const(Zip, "CM_BZIP2", INT2NUM(ZIP_CM_BZIP2));
2130
+
2131
+ rb_define_const(Zip, "EM_NONE", INT2NUM(ZIP_EM_NONE));
2132
+ rb_define_const(Zip, "EM_TRAD_PKWARE", INT2NUM(ZIP_EM_TRAD_PKWARE));
2133
+ // XXX: Strong Encryption Header not parsed yet
2134
+ }
2135
+ #include <string.h>
2136
+
2137
+ #include "zip.h"
2138
+ #include "zipint.h"
2139
+ #include "zipruby_zip_source_proc.h"
2140
+ #include "ruby.h"
2141
+
2142
+ static VALUE proc_call(VALUE proc) {
2143
+ return rb_funcall(proc, rb_intern("call"), 0);
2144
+ }
2145
+
2146
+ static ssize_t read_proc(void *state, void *data, size_t len, enum zip_source_cmd cmd) {
2147
+ struct read_proc *z;
2148
+ VALUE src;
2149
+ char *buf;
2150
+ size_t n;
2151
+
2152
+ z = (struct read_proc *) state;
2153
+ buf = (char *) data;
2154
+
2155
+ switch (cmd) {
2156
+ case ZIP_SOURCE_OPEN:
2157
+ return 0;
2158
+
2159
+ case ZIP_SOURCE_READ:
2160
+ src = rb_protect(proc_call, z->proc, NULL);
2161
+
2162
+ if (TYPE(src) != T_STRING) {
2163
+ return 0;
2164
+ }
2165
+
2166
+ n = RSTRING_LEN(src);
2167
+
2168
+ if (n > 0) {
2169
+ n = (n > len) ? len : n;
2170
+ memcpy(buf, RSTRING_PTR(src), n);
2171
+ }
2172
+
2173
+ return n;
2174
+
2175
+ case ZIP_SOURCE_CLOSE:
2176
+ return 0;
2177
+
2178
+ case ZIP_SOURCE_STAT:
2179
+ {
2180
+ struct zip_stat *st = (struct zip_stat *)data;
2181
+ zip_stat_init(st);
2182
+ st->mtime = NUM2LONG(rb_funcall(z->mtime, rb_intern("tv_sec"), 0));
2183
+ return sizeof(*st);
2184
+ }
2185
+
2186
+ case ZIP_SOURCE_ERROR:
2187
+ return 0;
2188
+
2189
+ case ZIP_SOURCE_FREE:
2190
+ free(z);
2191
+ return 0;
2192
+ }
2193
+
2194
+ return -1;
2195
+ }
2196
+
2197
+ struct zip_source *zip_source_proc(struct zip *za, struct read_proc *z) {
2198
+ struct zip_source *zs;
2199
+ zs = zip_source_function(za, read_proc, z);
2200
+ return zs;
2201
+ }