zipruby 0.2.6-mswin32 → 0.2.8-mswin32

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.

Files changed (3) hide show
  1. data/lib/i386-mswin32/zipruby.so +0 -0
  2. data/zipruby.c +345 -4
  3. metadata +2 -2
Binary file
data/zipruby.c CHANGED
@@ -1,4 +1,177 @@
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(src)->len < 1) {
155
+ break;
156
+ }
157
+
158
+ #ifdef _WIN32
159
+ if (_write(fd, StringValuePtr(src), RSTRING(src)->len) == -1) {
160
+ return -1;
161
+ }
162
+ #else
163
+ if (write(fd, StringValuePtr(src), RSTRING(src)->len) == -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
+ }
2
175
  #ifdef _WIN32
3
176
  __declspec(dllexport) void Init_zipruby(void);
4
177
  #endif
@@ -23,6 +196,7 @@ void Init_zipruby() {
23
196
  #include "zipruby.h"
24
197
  #include "zipruby_archive.h"
25
198
  #include "zipruby_zip_source_proc.h"
199
+ #include "tmpfile.h"
26
200
  #include "ruby.h"
27
201
  #include "rubyio.h"
28
202
 
@@ -30,6 +204,7 @@ static VALUE zipruby_archive_alloc(VALUE klass);
30
204
  static void zipruby_archive_mark(struct zipruby_archive *p);
31
205
  static void zipruby_archive_free(struct zipruby_archive *p);
32
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);
33
208
  static VALUE zipruby_archive_s_decrypt(VALUE self, VALUE path, VALUE password);
34
209
  static VALUE zipruby_archive_s_encrypt(VALUE self, VALUE path, VALUE password);
35
210
  static VALUE zipruby_archive_close(VALUE self);
@@ -66,6 +241,7 @@ static VALUE zipruby_archive_commit(VALUE self);
66
241
  static VALUE zipruby_archive_is_open(VALUE self);
67
242
  static VALUE zipruby_archive_decrypt(VALUE self, VALUE password);
68
243
  static VALUE zipruby_archive_encrypt(VALUE self, VALUE password);
244
+ static VALUE zipruby_archive_read(VALUE self);
69
245
 
70
246
  extern VALUE Zip;
71
247
  VALUE Archive;
@@ -78,6 +254,7 @@ void Init_zipruby_archive() {
78
254
  rb_define_alloc_func(Archive, zipruby_archive_alloc);
79
255
  rb_include_module(Archive, rb_mEnumerable);
80
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);
81
258
  rb_define_singleton_method(Archive, "decrypt", zipruby_archive_s_decrypt, 2);
82
259
  rb_define_singleton_method(Archive, "encrypt", zipruby_archive_s_encrypt, 2);
83
260
  rb_define_method(Archive, "close", zipruby_archive_close, 0);
@@ -117,6 +294,7 @@ void Init_zipruby_archive() {
117
294
  rb_define_method(Archive, "open?", zipruby_archive_is_open, 0);
118
295
  rb_define_method(Archive, "decrypt", zipruby_archive_decrypt, 1);
119
296
  rb_define_method(Archive, "encrypt", zipruby_archive_encrypt, 1);
297
+ rb_define_method(Archive, "read", zipruby_archive_read, 0);
120
298
  }
121
299
 
122
300
  static VALUE zipruby_archive_alloc(VALUE klass) {
@@ -125,15 +303,23 @@ static VALUE zipruby_archive_alloc(VALUE klass) {
125
303
  p->archive = NULL;
126
304
  p->path = Qnil;
127
305
  p->flags = 0;
306
+ p->tmpfilnam = NULL;
307
+ p->buffer = Qnil;
128
308
 
129
309
  return Data_Wrap_Struct(klass, zipruby_archive_mark, zipruby_archive_free, p);
130
310
  }
131
311
 
132
312
  static void zipruby_archive_mark(struct zipruby_archive *p) {
133
313
  rb_gc_mark(p->path);
314
+ rb_gc_mark(p->buffer);
134
315
  }
135
316
 
136
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
+
137
323
  xfree(p);
138
324
  }
139
325
 
@@ -181,6 +367,76 @@ static VALUE zipruby_archive_s_open(int argc, VALUE *argv, VALUE self) {
181
367
  }
182
368
  }
183
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 = StringValuePtr(buffer);
398
+ len = RSTRING(buffer)->len;
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
+
184
440
  /* */
185
441
  static VALUE zipruby_archive_s_decrypt(VALUE self, VALUE path, VALUE password) {
186
442
  int errorp, wrongpwd;
@@ -236,6 +492,7 @@ static VALUE zipruby_archive_s_encrypt(VALUE self, VALUE path, VALUE password) {
236
492
  /* */
237
493
  static VALUE zipruby_archive_close(VALUE self) {
238
494
  struct zipruby_archive *p_archive;
495
+ int changed, survivors;
239
496
 
240
497
  if (!zipruby_archive_is_open(self)) {
241
498
  return Qfalse;
@@ -244,14 +501,20 @@ static VALUE zipruby_archive_close(VALUE self) {
244
501
  Data_Get_Struct(self, struct zipruby_archive, p_archive);
245
502
  Check_Archive(p_archive);
246
503
 
504
+ changed = _zip_changed(p_archive->archive, &survivors);
505
+
247
506
  if (zip_close(p_archive->archive) == -1) {
248
507
  zip_unchange_all(p_archive->archive);
249
508
  zip_unchange_archive(p_archive->archive);
250
509
  rb_raise(Error, "Close archive failed: %s", zip_strerror(p_archive->archive));
251
510
  }
252
511
 
512
+ if (!NIL_P(p_archive->buffer) && changed) {
513
+ rb_funcall(p_archive->buffer, rb_intern("replace"), 1, rb_funcall(self, rb_intern("read"), 0));
514
+ }
515
+
516
+ zipruby_rmtmp(p_archive->tmpfilnam);
253
517
  p_archive->archive = NULL;
254
- p_archive->path = Qnil;
255
518
  p_archive->flags = 0;
256
519
 
257
520
  return Qtrue;
@@ -1087,17 +1350,24 @@ static VALUE zipruby_archive_each(VALUE self) {
1087
1350
  /* */
1088
1351
  static VALUE zipruby_archive_commit(VALUE self) {
1089
1352
  struct zipruby_archive *p_archive;
1353
+ int changed, survivors;
1090
1354
  int errorp;
1091
1355
 
1092
1356
  Data_Get_Struct(self, struct zipruby_archive, p_archive);
1093
1357
  Check_Archive(p_archive);
1094
1358
 
1359
+ changed = _zip_changed(p_archive->archive, &survivors);
1360
+
1095
1361
  if (zip_close(p_archive->archive) == -1) {
1096
1362
  zip_unchange_all(p_archive->archive);
1097
1363
  zip_unchange_archive(p_archive->archive);
1098
1364
  rb_raise(Error, "Commit archive failed: %s", zip_strerror(p_archive->archive));
1099
1365
  }
1100
1366
 
1367
+ if (!NIL_P(p_archive->buffer) && changed) {
1368
+ rb_funcall(p_archive->buffer, rb_intern("replace"), 1, rb_funcall(self, rb_intern("read"), 0));
1369
+ }
1370
+
1101
1371
  p_archive->archive = NULL;
1102
1372
  p_archive->flags = (p_archive->flags & ~(ZIP_CREATE | ZIP_EXCL));
1103
1373
 
@@ -1122,6 +1392,7 @@ static VALUE zipruby_archive_is_open(VALUE self) {
1122
1392
  static VALUE zipruby_archive_decrypt(VALUE self, VALUE password) {
1123
1393
  struct zipruby_archive *p_archive;
1124
1394
  long pwdlen;
1395
+ int changed, survivors;
1125
1396
  int errorp;
1126
1397
 
1127
1398
  Check_Type(password, T_STRING);
@@ -1136,12 +1407,18 @@ static VALUE zipruby_archive_decrypt(VALUE self, VALUE password) {
1136
1407
  Data_Get_Struct(self, struct zipruby_archive, p_archive);
1137
1408
  Check_Archive(p_archive);
1138
1409
 
1410
+ changed = _zip_changed(p_archive->archive, &survivors);
1411
+
1139
1412
  if (zip_close(p_archive->archive) == -1) {
1140
1413
  zip_unchange_all(p_archive->archive);
1141
1414
  zip_unchange_archive(p_archive->archive);
1142
1415
  rb_raise(Error, "Decrypt archive failed: %s", zip_strerror(p_archive->archive));
1143
1416
  }
1144
1417
 
1418
+ if (!NIL_P(p_archive->buffer) && changed) {
1419
+ rb_funcall(p_archive->buffer, rb_intern("replace"), 1, rb_funcall(self, rb_intern("read"), 0));
1420
+ }
1421
+
1145
1422
  p_archive->archive = NULL;
1146
1423
  p_archive->flags = (p_archive->flags & ~(ZIP_CREATE | ZIP_EXCL));
1147
1424
 
@@ -1160,6 +1437,7 @@ static VALUE zipruby_archive_decrypt(VALUE self, VALUE password) {
1160
1437
  static VALUE zipruby_archive_encrypt(VALUE self, VALUE password) {
1161
1438
  struct zipruby_archive *p_archive;
1162
1439
  long pwdlen;
1440
+ int changed, survivors;
1163
1441
  int errorp;
1164
1442
 
1165
1443
  Check_Type(password, T_STRING);
@@ -1174,12 +1452,18 @@ static VALUE zipruby_archive_encrypt(VALUE self, VALUE password) {
1174
1452
  Data_Get_Struct(self, struct zipruby_archive, p_archive);
1175
1453
  Check_Archive(p_archive);
1176
1454
 
1455
+ changed = _zip_changed(p_archive->archive, &survivors);
1456
+
1177
1457
  if (zip_close(p_archive->archive) == -1) {
1178
1458
  zip_unchange_all(p_archive->archive);
1179
1459
  zip_unchange_archive(p_archive->archive);
1180
1460
  rb_raise(Error, "Encrypt archive failed: %s", zip_strerror(p_archive->archive));
1181
1461
  }
1182
1462
 
1463
+ if (!NIL_P(p_archive->buffer) && changed) {
1464
+ rb_funcall(p_archive->buffer, rb_intern("replace"), 1, rb_funcall(self, rb_intern("read"), 0));
1465
+ }
1466
+
1183
1467
  p_archive->archive = NULL;
1184
1468
  p_archive->flags = (p_archive->flags & ~(ZIP_CREATE | ZIP_EXCL));
1185
1469
 
@@ -1193,6 +1477,59 @@ static VALUE zipruby_archive_encrypt(VALUE self, VALUE password) {
1193
1477
 
1194
1478
  return Qnil;
1195
1479
  }
1480
+
1481
+ static VALUE zipruby_archive_read(VALUE self) {
1482
+ VALUE retval = Qnil;
1483
+ struct zipruby_archive *p_archive;
1484
+ FILE *fzip;
1485
+ char buf[DATA_BUFSIZE];
1486
+ ssize_t n;
1487
+ int block_given;
1488
+
1489
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1490
+
1491
+ if (NIL_P(p_archive->path)) {
1492
+ rb_raise(rb_eRuntimeError, "invalid Zip::Archive");
1493
+ }
1494
+
1495
+ #ifdef _WIN32
1496
+ if (fopen_s(&fzip ,StringValuePtr(p_archive->path), "rb") != 0) {
1497
+ rb_raise(Error, "Read archive failed: Cannot open archive");
1498
+ }
1499
+ #else
1500
+ if ((fzip = fopen(StringValuePtr(p_archive->path), "rb")) == NULL) {
1501
+ rb_raise(Error, "Read archive failed: Cannot open archive");
1502
+ }
1503
+ #endif
1504
+
1505
+ block_given = rb_block_given_p();
1506
+
1507
+ while ((n = fread(buf, 1, sizeof(buf), fzip)) > 0) {
1508
+ if (block_given) {
1509
+ rb_yield(rb_str_new(buf, n));
1510
+ } else {
1511
+ if (NIL_P(retval)) {
1512
+ retval = rb_str_new(buf, n);
1513
+ } else {
1514
+ rb_str_buf_cat(retval, buf, n);
1515
+ }
1516
+ }
1517
+ }
1518
+
1519
+ #ifdef RUBY_WIN32_H
1520
+ #undef fclose
1521
+ fclose(fzip);
1522
+ #define fclose(f) rb_w32_fclose(f)
1523
+ #else
1524
+ fclose(fzip);
1525
+ #endif
1526
+
1527
+ if (n == -1) {
1528
+ rb_raise(Error, "Read archive failed");
1529
+ }
1530
+
1531
+ return retval;
1532
+ }
1196
1533
  #include "zipruby.h"
1197
1534
  #include "zipruby_error.h"
1198
1535
  #include "ruby.h"
@@ -1784,6 +2121,7 @@ void Init_zipruby_zip() {
1784
2121
  rb_define_const(Zip, "CREATE", INT2NUM(ZIP_CREATE));
1785
2122
  rb_define_const(Zip, "EXCL", INT2NUM(ZIP_EXCL));
1786
2123
  rb_define_const(Zip, "CHECKCONS", INT2NUM(ZIP_CHECKCONS));
2124
+ rb_define_const(Zip, "TRUNC", INT2NUM(ZIP_TRUNC));
1787
2125
 
1788
2126
  rb_define_const(Zip, "FL_NOCASE", INT2NUM(ZIP_FL_NOCASE));
1789
2127
  rb_define_const(Zip, "FL_NODIR", INT2NUM(ZIP_FL_NODIR));
@@ -1814,6 +2152,10 @@ void Init_zipruby_zip() {
1814
2152
  #include "zipruby_zip_source_proc.h"
1815
2153
  #include "ruby.h"
1816
2154
 
2155
+ static VALUE proc_call(VALUE proc) {
2156
+ return rb_funcall(proc, rb_intern("call"), 0);
2157
+ }
2158
+
1817
2159
  static ssize_t read_proc(void *state, void *data, size_t len, enum zip_source_cmd cmd) {
1818
2160
  struct read_proc *z;
1819
2161
  VALUE src;
@@ -1828,13 +2170,12 @@ static ssize_t read_proc(void *state, void *data, size_t len, enum zip_source_cm
1828
2170
  return 0;
1829
2171
 
1830
2172
  case ZIP_SOURCE_READ:
1831
- src = rb_funcall(z->proc, rb_intern("call"), 1, ULONG2NUM(len));
2173
+ src = rb_protect(proc_call, z->proc, NULL);
1832
2174
 
1833
- if (NIL_P(src)) {
2175
+ if (TYPE(src) != T_STRING) {
1834
2176
  return 0;
1835
2177
  }
1836
2178
 
1837
- src = rb_check_convert_type(src, T_STRING, "String", "to_s");
1838
2179
  n = RSTRING(src)->len;
1839
2180
 
1840
2181
  if (n > 0) {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zipruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.2.8
5
5
  platform: mswin32
6
6
  authors:
7
7
  - winebarrel
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-07-13 00:00:00 +09:00
12
+ date: 2008-07-17 00:00:00 +09:00
13
13
  default_executable:
14
14
  dependencies: []
15
15