zipruby 0.1.2 → 0.2.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/README.txt +48 -2
- data/ext/libzip.vcproj +4 -0
- data/ext/zip.h +3 -0
- data/ext/zip_close.c +11 -6
- data/ext/zip_crypt.c +291 -0
- data/ext/zip_dirent.c +4 -2
- data/ext/zipint.h +6 -0
- data/ext/zipruby.h +2 -1
- data/ext/zipruby_archive.c +28 -2
- data/ext/zipruby_file.c +39 -9
- data/zipruby.c +67 -11
- metadata +3 -2
data/README.txt
CHANGED
@@ -43,7 +43,24 @@ https://rubyforge.org/frs/?group_id=6124
|
|
43
43
|
|
44
44
|
# Zip::Archive includes Enumerable
|
45
45
|
entry_names = ar.map do |f|
|
46
|
-
f.
|
46
|
+
f.name
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# read huge entry
|
51
|
+
BUFSIZE = 8192
|
52
|
+
|
53
|
+
Zip::Archive.open('filename.zip') do |ar|
|
54
|
+
ar.each do |f|
|
55
|
+
buf = ''
|
56
|
+
|
57
|
+
while chunk = f.read(BUFSIZE)
|
58
|
+
buf << chunk
|
59
|
+
end
|
60
|
+
# or
|
61
|
+
# f.read do |chunk|
|
62
|
+
# buf << chunk
|
63
|
+
# end
|
47
64
|
end
|
48
65
|
end
|
49
66
|
|
@@ -62,6 +79,20 @@ https://rubyforge.org/frs/?group_id=6124
|
|
62
79
|
# add file to zip archive from buffer
|
63
80
|
ar.add_buffer('zoo.txt', 'Hello, world!')
|
64
81
|
end
|
82
|
+
|
83
|
+
# include directory in zip archive
|
84
|
+
Zip::Archive.open('filename.zip') do |ar|
|
85
|
+
ar.add_file('dirname/foo.txt', 'foo.txt')
|
86
|
+
# args: <entry name>, <source>
|
87
|
+
|
88
|
+
open('bar.txt') do |f|
|
89
|
+
ar.add_filep('dirname/bar.txt', f)
|
90
|
+
# args: <entry name>, <source>
|
91
|
+
end
|
92
|
+
|
93
|
+
ar.add_buffer('dirname/zoo.txt', 'Hello, world!')
|
94
|
+
# args: <entry name>, <source>
|
95
|
+
end
|
65
96
|
|
66
97
|
=== modifying zip archives
|
67
98
|
|
@@ -83,13 +114,28 @@ https://rubyforge.org/frs/?group_id=6124
|
|
83
114
|
ar.add_or_replace_file(3, 'foo.txt')
|
84
115
|
end
|
85
116
|
|
86
|
-
#
|
117
|
+
# append comment
|
118
|
+
Zip::Archive.open('filename.zip') do |ar|
|
119
|
+
ar.comment = <<-EOS
|
120
|
+
jugem jugem gokou no surikere
|
121
|
+
kaijari suigyo no
|
122
|
+
suigyoumatsu unraimatsu furaimatsu
|
123
|
+
EOS
|
124
|
+
end
|
125
|
+
|
126
|
+
# ar1 import ar2 entries
|
87
127
|
Zip::Archive.open('ar1.zip') do |ar1|
|
88
128
|
Zip::Archive.open('ar2.zip') do |ar2|
|
89
129
|
ar1.update(ar2)
|
90
130
|
end
|
91
131
|
end
|
92
132
|
|
133
|
+
=== decrypt zip archives
|
134
|
+
|
135
|
+
require 'zipruby'
|
136
|
+
|
137
|
+
Zip::Archive.decrypt('filename.zip', 'password')
|
138
|
+
|
93
139
|
== License
|
94
140
|
Copyright (c) 2008 SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
95
141
|
All rights reserved.
|
data/ext/libzip.vcproj
CHANGED
data/ext/zip.h
CHANGED
@@ -203,6 +203,9 @@ const char *zip_strerror(struct zip *);
|
|
203
203
|
int zip_unchange(struct zip *, int);
|
204
204
|
int zip_unchange_all(struct zip *);
|
205
205
|
int zip_unchange_archive(struct zip *);
|
206
|
+
|
207
|
+
// modified for Zip/Ruby by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
208
|
+
int zip_decrypt(const char *path, const char *pwd, int pwdlen, int *errorp, int *wrongpwd);
|
206
209
|
|
207
210
|
#ifdef __cplusplus
|
208
211
|
}
|
data/ext/zip_close.c
CHANGED
@@ -58,10 +58,12 @@ static int add_data_comp(zip_source_callback, void *, struct zip_stat *,
|
|
58
58
|
static int add_data_uncomp(zip_source_callback, void *, struct zip_stat *,
|
59
59
|
FILE *, struct zip_error *);
|
60
60
|
static void ch_set_error(struct zip_error *, zip_source_callback, void *);
|
61
|
-
|
62
|
-
static int
|
61
|
+
// modified for Zip/Ruby by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
62
|
+
//static int copy_data(FILE *, off_t, FILE *, struct zip_error *);
|
63
|
+
//static int _zip_cdir_set_comment(struct zip_cdir *, struct zip *);
|
63
64
|
static int _zip_changed(struct zip *, int *);
|
64
|
-
|
65
|
+
// modified for Zip/Ruby by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
66
|
+
//static char *_zip_create_temp_output(struct zip *, FILE **);
|
65
67
|
|
66
68
|
|
67
69
|
|
@@ -451,7 +453,8 @@ ch_set_error(struct zip_error *error, zip_source_callback cb, void *ud)
|
|
451
453
|
|
452
454
|
|
453
455
|
|
454
|
-
|
456
|
+
// modified for Zip/Ruby by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
457
|
+
/*static*/ int
|
455
458
|
copy_data(FILE *fs, off_t len, FILE *ft, struct zip_error *error)
|
456
459
|
{
|
457
460
|
char buf[BUFSIZE];
|
@@ -484,7 +487,8 @@ copy_data(FILE *fs, off_t len, FILE *ft, struct zip_error *error)
|
|
484
487
|
|
485
488
|
|
486
489
|
|
487
|
-
|
490
|
+
// modified for Zip/Ruby by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
491
|
+
/*static*/ int
|
488
492
|
_zip_cdir_set_comment(struct zip_cdir *dest, struct zip *src)
|
489
493
|
{
|
490
494
|
if (src->ch_comment_len != -1) {
|
@@ -533,7 +537,8 @@ _zip_changed(struct zip *za, int *survivorsp)
|
|
533
537
|
|
534
538
|
|
535
539
|
|
536
|
-
|
540
|
+
// modified for Zip/Ruby by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
541
|
+
/*static*/ char *
|
537
542
|
_zip_create_temp_output(struct zip *za, FILE **outp)
|
538
543
|
{
|
539
544
|
char *temp;
|
data/ext/zip_crypt.c
ADDED
@@ -0,0 +1,291 @@
|
|
1
|
+
/*
|
2
|
+
zip_crypt.c -- zip encryption support
|
3
|
+
Copyright (c) 2008 SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
4
|
+
based on zip_close.c
|
5
|
+
*/
|
6
|
+
#include <stdio.h>
|
7
|
+
#include <stdlib.h>
|
8
|
+
#include <string.h>
|
9
|
+
#include <errno.h>
|
10
|
+
#include <sys/types.h>
|
11
|
+
|
12
|
+
#ifdef _WIN32
|
13
|
+
#include <windows.h>
|
14
|
+
#include <io.h>
|
15
|
+
#define close(f) _close(f)
|
16
|
+
#define rename(s, d) (MoveFileExA((s), (d), MOVEFILE_REPLACE_EXISTING) ? 0 : -1)
|
17
|
+
#endif
|
18
|
+
|
19
|
+
#include "zip.h"
|
20
|
+
#include "zipint.h"
|
21
|
+
|
22
|
+
#define ZIPENC_HEAD_LEN 12
|
23
|
+
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
24
|
+
|
25
|
+
static zipenc_crc32(uLong crc, char c) {
|
26
|
+
return crc32(crc ^ 0xffffffffL, &c, 1) ^ 0xffffffffL;
|
27
|
+
}
|
28
|
+
|
29
|
+
static void update_keys(uLong *keys, char c) {
|
30
|
+
keys[0] = zipenc_crc32(keys[0], c);
|
31
|
+
keys[1] = keys[1] + (keys[0] & 0xff);
|
32
|
+
keys[1] = keys[1] * 134775813L + 1;
|
33
|
+
c = (char) (keys[1] >> 24);
|
34
|
+
keys[2] = zipenc_crc32(keys[2], c);
|
35
|
+
}
|
36
|
+
|
37
|
+
static unsigned char decrypt_byte(uLong *keys) {
|
38
|
+
unsigned short temp;
|
39
|
+
|
40
|
+
temp = (unsigned short) (keys[2] | 2);
|
41
|
+
return (temp * (temp ^ 1)) >> 8;
|
42
|
+
}
|
43
|
+
|
44
|
+
static void init_keys(uLong *keys, const char *password, size_t len) {
|
45
|
+
int i;
|
46
|
+
|
47
|
+
keys[0] = 305419896L;
|
48
|
+
keys[1] = 591751049L;
|
49
|
+
keys[2] = 878082192L;
|
50
|
+
|
51
|
+
for (i = 0; i < len; i++) {
|
52
|
+
update_keys(keys, password[i]);
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
static int decrypt_header(unsigned long *keys, char *buffer, struct zip_dirent *de) {
|
57
|
+
int i;
|
58
|
+
char c;
|
59
|
+
unsigned short dostime, dosdate;
|
60
|
+
|
61
|
+
for (i = 0; i < ZIPENC_HEAD_LEN; i++) {
|
62
|
+
c = buffer[i] ^ decrypt_byte(keys);
|
63
|
+
update_keys(keys, c);
|
64
|
+
buffer[i] = c;
|
65
|
+
}
|
66
|
+
|
67
|
+
_zip_u2d_time(de->last_mod, &dostime, &dosdate);
|
68
|
+
|
69
|
+
if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
|
70
|
+
return ((c & 0xff) == (de->crc >> 24)) ? 0 : -1;
|
71
|
+
} else {
|
72
|
+
return ((c & 0xff) == (dostime >> 8)) ? 0 : -1;
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
static void decrypt_data(uLong *keys, char *buffer, size_t n) {
|
77
|
+
int i;
|
78
|
+
|
79
|
+
for (i = 0; i < n; i++) {
|
80
|
+
char temp = buffer[i] ^ decrypt_byte(keys);
|
81
|
+
update_keys(keys, temp);
|
82
|
+
buffer[i] = temp;
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
static int copy_decrypt(FILE *src, off_t len, const char *pwd, int pwdlen, struct zip_dirent *de, FILE *dest, struct zip_error *error, int *wrongpwd) {
|
87
|
+
char buf[BUFSIZE];
|
88
|
+
uLong keys[3];
|
89
|
+
int n;
|
90
|
+
|
91
|
+
*wrongpwd = 0;
|
92
|
+
|
93
|
+
if (len == 0) {
|
94
|
+
return 0;
|
95
|
+
}
|
96
|
+
|
97
|
+
init_keys(keys, pwd, pwdlen);
|
98
|
+
|
99
|
+
if (fread(buf, 1, ZIPENC_HEAD_LEN, src) < 0) {
|
100
|
+
_zip_error_set(error, ZIP_ER_READ, errno);
|
101
|
+
}
|
102
|
+
|
103
|
+
if (decrypt_header(keys, buf, de) == -1) {
|
104
|
+
// XXX: _zip_error_set
|
105
|
+
*wrongpwd = 1;
|
106
|
+
return -1;
|
107
|
+
}
|
108
|
+
|
109
|
+
while (len > 0) {
|
110
|
+
if ((n = fread(buf, 1, MIN(len, sizeof(buf)), src)) < 0) {
|
111
|
+
_zip_error_set(error, ZIP_ER_READ, errno);
|
112
|
+
return -1;
|
113
|
+
} else if (n == 0) {
|
114
|
+
_zip_error_set(error, ZIP_ER_EOF, 0);
|
115
|
+
return -1;
|
116
|
+
}
|
117
|
+
|
118
|
+
decrypt_data(keys, buf, n);
|
119
|
+
|
120
|
+
if (fwrite(buf, 1, n, dest) != ((size_t) n)) {
|
121
|
+
_zip_error_set(error, ZIP_ER_WRITE, errno);
|
122
|
+
return -1;
|
123
|
+
}
|
124
|
+
|
125
|
+
len -= n;
|
126
|
+
}
|
127
|
+
|
128
|
+
return 0;
|
129
|
+
}
|
130
|
+
|
131
|
+
static int _zip_crypt(struct zip *za, const char *pwd, int pwdlen, int decrypt, int *wrongpwd) {
|
132
|
+
int i, error = 0;
|
133
|
+
char *temp;
|
134
|
+
FILE *out;
|
135
|
+
#ifndef _WIN32
|
136
|
+
mode_t mask;
|
137
|
+
#endif
|
138
|
+
struct zip_cdir *cd;
|
139
|
+
struct zip_dirent de;
|
140
|
+
int reopen_on_error = 0;
|
141
|
+
|
142
|
+
if (za == NULL) {
|
143
|
+
return -1;
|
144
|
+
}
|
145
|
+
|
146
|
+
if (za->nentry < 1) {
|
147
|
+
_zip_free(za);
|
148
|
+
return 0;
|
149
|
+
}
|
150
|
+
|
151
|
+
if ((cd = _zip_cdir_new(za->nentry, &za->error)) == NULL) {
|
152
|
+
return -1;
|
153
|
+
}
|
154
|
+
|
155
|
+
for (i = 0; i < za->nentry; i++) {
|
156
|
+
_zip_dirent_init(&cd->entry[i]);
|
157
|
+
}
|
158
|
+
|
159
|
+
if (_zip_cdir_set_comment(cd, za) == -1) {
|
160
|
+
_zip_cdir_free(cd);
|
161
|
+
return -1;
|
162
|
+
}
|
163
|
+
|
164
|
+
if ((temp = _zip_create_temp_output(za, &out)) == NULL) {
|
165
|
+
_zip_cdir_free(cd);
|
166
|
+
return -1;
|
167
|
+
}
|
168
|
+
|
169
|
+
for (i = 0; i < za->nentry; i++) {
|
170
|
+
int encrypted;
|
171
|
+
|
172
|
+
if (fseeko(za->zp, za->cdir->entry[i].offset, SEEK_SET) != 0) {
|
173
|
+
_zip_error_set(&za->error, ZIP_ER_SEEK, errno);
|
174
|
+
error = 1;
|
175
|
+
break;
|
176
|
+
}
|
177
|
+
|
178
|
+
if (_zip_dirent_read(&de, za->zp, NULL, 0, 1, &za->error) != 0) {
|
179
|
+
error = 1;
|
180
|
+
break;
|
181
|
+
}
|
182
|
+
|
183
|
+
if (de.bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
|
184
|
+
de.crc = za->cdir->entry[i].crc;
|
185
|
+
de.comp_size = za->cdir->entry[i].comp_size;
|
186
|
+
de.uncomp_size = za->cdir->entry[i].uncomp_size;
|
187
|
+
de.bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR;
|
188
|
+
}
|
189
|
+
|
190
|
+
memcpy(cd->entry + i, za->cdir->entry + i, sizeof(cd->entry[i]));
|
191
|
+
cd->entry[i].offset = ftello(out);
|
192
|
+
|
193
|
+
encrypted = de.bitflags & ZIP_GPBF_ENCRYPTED;
|
194
|
+
|
195
|
+
if (decrypt && encrypted) {
|
196
|
+
de.comp_size -= ZIPENC_HEAD_LEN;
|
197
|
+
de.bitflags &= ~ZIP_GPBF_ENCRYPTED;
|
198
|
+
cd->entry[i].comp_size -= ZIPENC_HEAD_LEN;
|
199
|
+
cd->entry[i].bitflags &= ~ZIP_GPBF_ENCRYPTED;
|
200
|
+
} else if (!decrypt && !encrypted) {
|
201
|
+
// XXX
|
202
|
+
}
|
203
|
+
|
204
|
+
if (_zip_dirent_write(&de, out, 1, &za->error) < 0) {
|
205
|
+
error = 1;
|
206
|
+
break;
|
207
|
+
}
|
208
|
+
|
209
|
+
if (decrypt && encrypted) {
|
210
|
+
error = (copy_decrypt(za->zp, cd->entry[i].comp_size, pwd, pwdlen, &de, out, &za->error, wrongpwd) < 0);
|
211
|
+
} else if (!decrypt && !encrypted) {
|
212
|
+
// XXX
|
213
|
+
error = (copy_data(za->zp, cd->entry[i].comp_size, out, &za->error) < 0);
|
214
|
+
} else {
|
215
|
+
error = (copy_data(za->zp, cd->entry[i].comp_size, out, &za->error) < 0);
|
216
|
+
}
|
217
|
+
|
218
|
+
if (error) {
|
219
|
+
break;
|
220
|
+
}
|
221
|
+
|
222
|
+
_zip_dirent_finalize(&de);
|
223
|
+
}
|
224
|
+
|
225
|
+
if (!error && _zip_cdir_write(cd, out, &za->error) < 0) {
|
226
|
+
error = 1;
|
227
|
+
}
|
228
|
+
|
229
|
+
cd->nentry = 0;
|
230
|
+
_zip_cdir_free(cd);
|
231
|
+
|
232
|
+
if (error) {
|
233
|
+
_zip_dirent_finalize(&de);
|
234
|
+
fclose(out);
|
235
|
+
remove(temp);
|
236
|
+
free(temp);
|
237
|
+
return -1;
|
238
|
+
}
|
239
|
+
|
240
|
+
if (fclose(out) != 0) {
|
241
|
+
_zip_error_set(&za->error, ZIP_ER_CLOSE, errno);
|
242
|
+
remove(temp);
|
243
|
+
free(temp);
|
244
|
+
return -1;
|
245
|
+
}
|
246
|
+
|
247
|
+
if (za->zp) {
|
248
|
+
fclose(za->zp);
|
249
|
+
za->zp = NULL;
|
250
|
+
reopen_on_error = 1;
|
251
|
+
}
|
252
|
+
|
253
|
+
if (rename(temp, za->zn) != 0) {
|
254
|
+
_zip_error_set(&za->error, ZIP_ER_RENAME, errno);
|
255
|
+
remove(temp);
|
256
|
+
free(temp);
|
257
|
+
|
258
|
+
if (reopen_on_error) {
|
259
|
+
za->zp = fopen(za->zn, "rb");
|
260
|
+
}
|
261
|
+
|
262
|
+
return -1;
|
263
|
+
}
|
264
|
+
|
265
|
+
#ifndef _WIN32
|
266
|
+
mask = umask(0);
|
267
|
+
umask(mask);
|
268
|
+
chmod(za->zn, 0666&~mask);
|
269
|
+
#endif
|
270
|
+
|
271
|
+
free(temp);
|
272
|
+
return 0;
|
273
|
+
}
|
274
|
+
|
275
|
+
int zip_decrypt(const char *path, const char *pwd, int pwdlen, int *errorp, int *wrongpwd) {
|
276
|
+
struct zip *za;
|
277
|
+
int res;
|
278
|
+
|
279
|
+
if (pwd == NULL || pwdlen < 1) {
|
280
|
+
return -1;
|
281
|
+
}
|
282
|
+
|
283
|
+
if ((za = zip_open(path, 0, errorp)) == NULL) {
|
284
|
+
return -1;
|
285
|
+
}
|
286
|
+
|
287
|
+
res = _zip_crypt(za, pwd, pwdlen, 1, wrongpwd);
|
288
|
+
_zip_free(za);
|
289
|
+
|
290
|
+
return res;
|
291
|
+
}
|
data/ext/zip_dirent.c
CHANGED
@@ -48,7 +48,8 @@
|
|
48
48
|
static time_t _zip_d2u_time(int, int);
|
49
49
|
static char *_zip_readfpstr(FILE *, unsigned int, int, struct zip_error *);
|
50
50
|
static char *_zip_readstr(unsigned char **, int, int, struct zip_error *);
|
51
|
-
|
51
|
+
// modified for Zip/Ruby by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
52
|
+
//static void _zip_u2d_time(time_t, unsigned short *, unsigned short *);
|
52
53
|
static void _zip_write2(unsigned short, FILE *);
|
53
54
|
static void _zip_write4(unsigned int, FILE *);
|
54
55
|
|
@@ -516,7 +517,8 @@ _zip_write4(unsigned int i, FILE *fp)
|
|
516
517
|
|
517
518
|
|
518
519
|
|
519
|
-
|
520
|
+
// modified for Zip/Ruby by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
521
|
+
/*static*/ void
|
520
522
|
_zip_u2d_time(time_t time, unsigned short *dtime, unsigned short *ddate)
|
521
523
|
{
|
522
524
|
struct tm *tm;
|
data/ext/zipint.h
CHANGED
@@ -237,4 +237,10 @@ int _zip_set_name(struct zip *, int, const char *);
|
|
237
237
|
int _zip_unchange(struct zip *, int, int);
|
238
238
|
void _zip_unchange_data(struct zip_entry *);
|
239
239
|
|
240
|
+
// modified for Zip/Ruby by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
241
|
+
int copy_data(FILE *fs, off_t len, FILE *ft, struct zip_error *error);
|
242
|
+
int _zip_cdir_set_comment(struct zip_cdir *, struct zip *);
|
243
|
+
char *_zip_create_temp_output(struct zip *, FILE **);
|
244
|
+
void _zip_u2d_time(time_t, unsigned short *, unsigned short *);
|
245
|
+
|
240
246
|
#endif /* zipint.h */
|
data/ext/zipruby.h
CHANGED
data/ext/zipruby_archive.c
CHANGED
@@ -9,6 +9,7 @@
|
|
9
9
|
static VALUE zipruby_archive_alloc(VALUE klass);
|
10
10
|
static void zipruby_archive_free(struct zipruby_archive *p);
|
11
11
|
static VALUE zipruby_archive_s_open(int argc, VALUE *argv, VALUE self);
|
12
|
+
static VALUE zipruby_archive_s_decrypt(VALUE self, VALUE path, VALUE password);
|
12
13
|
static VALUE zipruby_archive_close(VALUE self);
|
13
14
|
static VALUE zipruby_archive_num_files(VALUE self);
|
14
15
|
static VALUE zipruby_archive_get_name(int argc, VALUE *argv, VALUE self);
|
@@ -48,6 +49,7 @@ void Init_zipruby_archive() {
|
|
48
49
|
rb_define_alloc_func(Archive, zipruby_archive_alloc);
|
49
50
|
rb_include_module(Archive, rb_mEnumerable);
|
50
51
|
rb_define_singleton_method(Archive, "open", zipruby_archive_s_open, -1);
|
52
|
+
rb_define_singleton_method(Archive, "decrypt", zipruby_archive_s_decrypt, 2);
|
51
53
|
rb_define_method(Archive, "close", zipruby_archive_close, 0);
|
52
54
|
rb_define_method(Archive, "num_files", zipruby_archive_num_files, 0);
|
53
55
|
rb_define_method(Archive, "get_name", zipruby_archive_get_name, -1);
|
@@ -131,7 +133,27 @@ static VALUE zipruby_archive_s_open(int argc, VALUE *argv, VALUE self) {
|
|
131
133
|
} else {
|
132
134
|
return archive;
|
133
135
|
}
|
134
|
-
}
|
136
|
+
}
|
137
|
+
|
138
|
+
/* */
|
139
|
+
static VALUE zipruby_archive_s_decrypt(VALUE self, VALUE path, VALUE password) {
|
140
|
+
int errorp, wrongpwd;
|
141
|
+
|
142
|
+
Check_Type(path, T_STRING);
|
143
|
+
Check_Type(password, T_STRING);
|
144
|
+
|
145
|
+
if (zip_decrypt(StringValuePtr(path), StringValuePtr(password), RSTRING(password)->len, &errorp, &wrongpwd) == -1) {
|
146
|
+
if (wrongpwd) {
|
147
|
+
rb_raise(Error, "Decrypt archive failed - %s: Wrong password", StringValuePtr(path));
|
148
|
+
} else {
|
149
|
+
char errstr[ERRSTR_BUFSIZE];
|
150
|
+
zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
|
151
|
+
rb_raise(Error, "Decrypt archive failed - %s: %s", StringValuePtr(path), errstr);
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
return Qnil;
|
156
|
+
}
|
135
157
|
|
136
158
|
/* */
|
137
159
|
static VALUE zipruby_archive_close(VALUE self) {
|
@@ -269,7 +291,11 @@ static VALUE zipruby_archive_replace_buffer(VALUE self, VALUE index, VALUE sourc
|
|
269
291
|
Check_Archive(p_archive);
|
270
292
|
|
271
293
|
len = RSTRING(source)->len;
|
272
|
-
|
294
|
+
|
295
|
+
if ((data = malloc(len)) == NULL) {
|
296
|
+
rb_raise(rb_eRuntimeError, "Replace file failed: Cannot allocate memory");
|
297
|
+
}
|
298
|
+
|
273
299
|
memcpy(data, StringValuePtr(source), len);
|
274
300
|
|
275
301
|
if ((zsource = zip_source_buffer(p_archive->archive, data, len, 1)) == NULL) {
|
data/ext/zipruby_file.c
CHANGED
@@ -13,13 +13,15 @@
|
|
13
13
|
#include "zipruby_stat.h"
|
14
14
|
#include "ruby.h"
|
15
15
|
|
16
|
+
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
17
|
+
|
16
18
|
static VALUE zipruby_file(VALUE klass);
|
17
19
|
static VALUE zipruby_file_alloc(VALUE klass);
|
18
20
|
static void zipruby_file_mark(struct zipruby_file *p);
|
19
21
|
static void zipruby_file_free(struct zipruby_file *p);
|
20
22
|
static VALUE zipruby_file_initialize(int argc, VALUE *argv, VALUE self);
|
21
23
|
static VALUE zipruby_file_close(VALUE self);
|
22
|
-
static VALUE zipruby_file_read(VALUE self);
|
24
|
+
static VALUE zipruby_file_read(int argc, VALUE *argv, VALUE self);
|
23
25
|
static VALUE zipruby_file_stat(VALUE self);
|
24
26
|
static VALUE zipruby_file_get_comment(int argc, VALUE *argv, VALUE self);
|
25
27
|
static VALUE zipruby_file_set_comment(VALUE self, VALUE comment);
|
@@ -46,7 +48,7 @@ void Init_zipruby_file() {
|
|
46
48
|
rb_define_alloc_func(File, zipruby_file_alloc);
|
47
49
|
rb_define_method(File, "initialize", zipruby_file_initialize, -1);
|
48
50
|
rb_define_method(File, "close", zipruby_file_close, 0);
|
49
|
-
rb_define_method(File, "read", zipruby_file_read,
|
51
|
+
rb_define_method(File, "read", zipruby_file_read, -1);
|
50
52
|
rb_define_method(File, "stat", zipruby_file_stat, 0);
|
51
53
|
rb_define_method(File, "get_comment", zipruby_file_get_comment, -1);
|
52
54
|
rb_define_method(File, "comment", zipruby_file_get_comment, -1);
|
@@ -162,27 +164,55 @@ static VALUE zipruby_file_close(VALUE self) {
|
|
162
164
|
}
|
163
165
|
|
164
166
|
/* */
|
165
|
-
static VALUE zipruby_file_read(VALUE self) {
|
167
|
+
static VALUE zipruby_file_read(int argc, VALUE *argv, VALUE self) {
|
168
|
+
VALUE size, retval = Qnil;
|
166
169
|
struct zipruby_file *p_file;
|
167
170
|
struct zip_stat sb;
|
168
|
-
|
171
|
+
int block_given;
|
172
|
+
size_t bytes_left;
|
173
|
+
char buf[DATA_BUFSIZE];
|
174
|
+
ssize_t n;
|
169
175
|
|
176
|
+
rb_scan_args(argc, argv, "01", &size);
|
170
177
|
Data_Get_Struct(self, struct zipruby_file, p_file);
|
171
178
|
Check_File(p_file);
|
172
|
-
|
173
179
|
zip_stat_init(&sb);
|
174
180
|
|
175
181
|
if (zip_stat_index(p_file->archive, p_file->sb->index, 0, &sb)) {
|
176
182
|
rb_raise(Error, "Read file failed: %s", zip_strerror(p_file->archive));
|
177
183
|
}
|
178
184
|
|
179
|
-
|
180
|
-
|
181
|
-
|
185
|
+
if (NIL_P(size)) {
|
186
|
+
bytes_left = sb.size;
|
187
|
+
} else {
|
188
|
+
bytes_left = NUM2LONG(size);
|
189
|
+
}
|
190
|
+
|
191
|
+
if (bytes_left <= 0) {
|
192
|
+
return Qnil;
|
193
|
+
}
|
194
|
+
|
195
|
+
block_given = rb_block_given_p();
|
196
|
+
|
197
|
+
while ((n = zip_fread(p_file->file, buf, MIN(bytes_left, sizeof(buf)))) > 0) {
|
198
|
+
if (block_given) {
|
199
|
+
rb_yield(rb_str_new(buf, n));
|
200
|
+
} else {
|
201
|
+
if (NIL_P(retval)) {
|
202
|
+
retval = rb_str_new(buf, n);
|
203
|
+
} else {
|
204
|
+
rb_str_buf_cat(retval, buf, n);
|
205
|
+
}
|
206
|
+
}
|
207
|
+
|
208
|
+
bytes_left -= n;
|
209
|
+
}
|
210
|
+
|
211
|
+
if (n == -1) {
|
182
212
|
rb_raise(Error, "Read file failed: %s", zip_file_strerror(p_file->file));
|
183
213
|
}
|
184
214
|
|
185
|
-
return
|
215
|
+
return retval;
|
186
216
|
}
|
187
217
|
|
188
218
|
/* */
|
data/zipruby.c
CHANGED
@@ -28,6 +28,7 @@ void Init_zipruby() {
|
|
28
28
|
static VALUE zipruby_archive_alloc(VALUE klass);
|
29
29
|
static void zipruby_archive_free(struct zipruby_archive *p);
|
30
30
|
static VALUE zipruby_archive_s_open(int argc, VALUE *argv, VALUE self);
|
31
|
+
static VALUE zipruby_archive_s_decrypt(VALUE self, VALUE path, VALUE password);
|
31
32
|
static VALUE zipruby_archive_close(VALUE self);
|
32
33
|
static VALUE zipruby_archive_num_files(VALUE self);
|
33
34
|
static VALUE zipruby_archive_get_name(int argc, VALUE *argv, VALUE self);
|
@@ -67,6 +68,7 @@ void Init_zipruby_archive() {
|
|
67
68
|
rb_define_alloc_func(Archive, zipruby_archive_alloc);
|
68
69
|
rb_include_module(Archive, rb_mEnumerable);
|
69
70
|
rb_define_singleton_method(Archive, "open", zipruby_archive_s_open, -1);
|
71
|
+
rb_define_singleton_method(Archive, "decrypt", zipruby_archive_s_decrypt, 2);
|
70
72
|
rb_define_method(Archive, "close", zipruby_archive_close, 0);
|
71
73
|
rb_define_method(Archive, "num_files", zipruby_archive_num_files, 0);
|
72
74
|
rb_define_method(Archive, "get_name", zipruby_archive_get_name, -1);
|
@@ -150,7 +152,27 @@ static VALUE zipruby_archive_s_open(int argc, VALUE *argv, VALUE self) {
|
|
150
152
|
} else {
|
151
153
|
return archive;
|
152
154
|
}
|
153
|
-
}
|
155
|
+
}
|
156
|
+
|
157
|
+
/* */
|
158
|
+
static VALUE zipruby_archive_s_decrypt(VALUE self, VALUE path, VALUE password) {
|
159
|
+
int errorp, wrongpwd;
|
160
|
+
|
161
|
+
Check_Type(path, T_STRING);
|
162
|
+
Check_Type(password, T_STRING);
|
163
|
+
|
164
|
+
if (zip_decrypt(StringValuePtr(path), StringValuePtr(password), RSTRING(password)->len, &errorp, &wrongpwd) == -1) {
|
165
|
+
if (wrongpwd) {
|
166
|
+
rb_raise(Error, "Decrypt archive failed - %s: Wrong password", StringValuePtr(path));
|
167
|
+
} else {
|
168
|
+
char errstr[ERRSTR_BUFSIZE];
|
169
|
+
zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
|
170
|
+
rb_raise(Error, "Decrypt archive failed - %s: %s", StringValuePtr(path), errstr);
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
return Qnil;
|
175
|
+
}
|
154
176
|
|
155
177
|
/* */
|
156
178
|
static VALUE zipruby_archive_close(VALUE self) {
|
@@ -288,7 +310,11 @@ static VALUE zipruby_archive_replace_buffer(VALUE self, VALUE index, VALUE sourc
|
|
288
310
|
Check_Archive(p_archive);
|
289
311
|
|
290
312
|
len = RSTRING(source)->len;
|
291
|
-
|
313
|
+
|
314
|
+
if ((data = malloc(len)) == NULL) {
|
315
|
+
rb_raise(rb_eRuntimeError, "Replace file failed: Cannot allocate memory");
|
316
|
+
}
|
317
|
+
|
292
318
|
memcpy(data, StringValuePtr(source), len);
|
293
319
|
|
294
320
|
if ((zsource = zip_source_buffer(p_archive->archive, data, len, 1)) == NULL) {
|
@@ -825,13 +851,15 @@ void Init_zipruby_error() {
|
|
825
851
|
#include "zipruby_stat.h"
|
826
852
|
#include "ruby.h"
|
827
853
|
|
854
|
+
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
855
|
+
|
828
856
|
static VALUE zipruby_file(VALUE klass);
|
829
857
|
static VALUE zipruby_file_alloc(VALUE klass);
|
830
858
|
static void zipruby_file_mark(struct zipruby_file *p);
|
831
859
|
static void zipruby_file_free(struct zipruby_file *p);
|
832
860
|
static VALUE zipruby_file_initialize(int argc, VALUE *argv, VALUE self);
|
833
861
|
static VALUE zipruby_file_close(VALUE self);
|
834
|
-
static VALUE zipruby_file_read(VALUE self);
|
862
|
+
static VALUE zipruby_file_read(int argc, VALUE *argv, VALUE self);
|
835
863
|
static VALUE zipruby_file_stat(VALUE self);
|
836
864
|
static VALUE zipruby_file_get_comment(int argc, VALUE *argv, VALUE self);
|
837
865
|
static VALUE zipruby_file_set_comment(VALUE self, VALUE comment);
|
@@ -858,7 +886,7 @@ void Init_zipruby_file() {
|
|
858
886
|
rb_define_alloc_func(File, zipruby_file_alloc);
|
859
887
|
rb_define_method(File, "initialize", zipruby_file_initialize, -1);
|
860
888
|
rb_define_method(File, "close", zipruby_file_close, 0);
|
861
|
-
rb_define_method(File, "read", zipruby_file_read,
|
889
|
+
rb_define_method(File, "read", zipruby_file_read, -1);
|
862
890
|
rb_define_method(File, "stat", zipruby_file_stat, 0);
|
863
891
|
rb_define_method(File, "get_comment", zipruby_file_get_comment, -1);
|
864
892
|
rb_define_method(File, "comment", zipruby_file_get_comment, -1);
|
@@ -974,27 +1002,55 @@ static VALUE zipruby_file_close(VALUE self) {
|
|
974
1002
|
}
|
975
1003
|
|
976
1004
|
/* */
|
977
|
-
static VALUE zipruby_file_read(VALUE self) {
|
1005
|
+
static VALUE zipruby_file_read(int argc, VALUE *argv, VALUE self) {
|
1006
|
+
VALUE size, retval = Qnil;
|
978
1007
|
struct zipruby_file *p_file;
|
979
1008
|
struct zip_stat sb;
|
980
|
-
|
1009
|
+
int block_given;
|
1010
|
+
size_t bytes_left;
|
1011
|
+
char buf[DATA_BUFSIZE];
|
1012
|
+
ssize_t n;
|
981
1013
|
|
1014
|
+
rb_scan_args(argc, argv, "01", &size);
|
982
1015
|
Data_Get_Struct(self, struct zipruby_file, p_file);
|
983
1016
|
Check_File(p_file);
|
984
|
-
|
985
1017
|
zip_stat_init(&sb);
|
986
1018
|
|
987
1019
|
if (zip_stat_index(p_file->archive, p_file->sb->index, 0, &sb)) {
|
988
1020
|
rb_raise(Error, "Read file failed: %s", zip_strerror(p_file->archive));
|
989
1021
|
}
|
990
1022
|
|
991
|
-
|
992
|
-
|
993
|
-
|
1023
|
+
if (NIL_P(size)) {
|
1024
|
+
bytes_left = sb.size;
|
1025
|
+
} else {
|
1026
|
+
bytes_left = NUM2LONG(size);
|
1027
|
+
}
|
1028
|
+
|
1029
|
+
if (bytes_left <= 0) {
|
1030
|
+
return Qnil;
|
1031
|
+
}
|
1032
|
+
|
1033
|
+
block_given = rb_block_given_p();
|
1034
|
+
|
1035
|
+
while ((n = zip_fread(p_file->file, buf, MIN(bytes_left, sizeof(buf)))) > 0) {
|
1036
|
+
if (block_given) {
|
1037
|
+
rb_yield(rb_str_new(buf, n));
|
1038
|
+
} else {
|
1039
|
+
if (NIL_P(retval)) {
|
1040
|
+
retval = rb_str_new(buf, n);
|
1041
|
+
} else {
|
1042
|
+
rb_str_buf_cat(retval, buf, n);
|
1043
|
+
}
|
1044
|
+
}
|
1045
|
+
|
1046
|
+
bytes_left -= n;
|
1047
|
+
}
|
1048
|
+
|
1049
|
+
if (n == -1) {
|
994
1050
|
rb_raise(Error, "Read file failed: %s", zip_file_strerror(p_file->file));
|
995
1051
|
}
|
996
1052
|
|
997
|
-
return
|
1053
|
+
return retval;
|
998
1054
|
}
|
999
1055
|
|
1000
1056
|
/* */
|
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.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- winebarrel
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-04-
|
12
|
+
date: 2008-04-30 00:00:00 +09:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -45,6 +45,7 @@ files:
|
|
45
45
|
- ext/zip_add.c
|
46
46
|
- ext/zip_add_dir.c
|
47
47
|
- ext/zip_close.c
|
48
|
+
- ext/zip_crypt.c
|
48
49
|
- ext/zip_delete.c
|
49
50
|
- ext/zip_dirent.c
|
50
51
|
- ext/zip_entry_free.c
|