Browse Source

- MFH: update to 0.9 (torrentzip support, files open only when necessary), windows fixes

PECL
Pierre Joye 18 years ago
parent
commit
490a342205
  1. 3
      ext/zip/config.w32
  2. 3
      ext/zip/lib/zip.h
  3. 188
      ext/zip/lib/zip_close.c
  4. 59
      ext/zip/lib/zip_dirent.c
  5. 4
      ext/zip/lib/zip_err_str.c
  6. 71
      ext/zip/lib/zip_filerange_crc.c
  7. 48
      ext/zip/lib/zip_get_archive_flag.c
  8. 23
      ext/zip/lib/zip_open.c
  9. 20
      ext/zip/lib/zip_rename.c
  10. 49
      ext/zip/lib/zip_set_archive_flag.c
  11. 17
      ext/zip/lib/zip_source_file.c
  12. 53
      ext/zip/lib/zip_source_filep.c
  13. 4
      ext/zip/lib/zip_source_zip.c
  14. 6
      ext/zip/lib/zip_unchange_archive.c
  15. 9
      ext/zip/lib/zipint.h

3
ext/zip/config.w32

@ -17,7 +17,8 @@ if (PHP_ZIP != "no") {
zip_error_get_sys_type.c zip_file_get_offset.c \
zip_get_name.c zip_replace.c zip_source_function.c \
zip_unchange.c zip_dirent.c zip_error_strerror.c \
zip_file_strerror.c zip_get_num_files.c \
zip_filerange_crc.c zip_file_strerror.c zip_get_num_files.c \
zip_get_archive_flag.c zip_set_archive_flag.c \
zip_set_name.c zip_source_zip.c zip_unchange_data.c \
zip_entry_free.c zip_error_to_str.c zip_fopen.c \
zip_name_locate.c zip_source_buffer.c zip_stat.c \

3
ext/zip/lib/zip.h

@ -70,6 +70,7 @@ BEGIN_EXTERN_C()
#define ZIP_FL_NODIR 2 /* ignore directory component */
#define ZIP_FL_COMPRESSED 4 /* read compressed data */
#define ZIP_FL_UNCHANGED 8 /* use original data, ignoring changes */
#define ZIP_FL_RECOMPRESS 16 /* force recompression of data */
/* archive global flags flags */
@ -161,8 +162,6 @@ enum zip_source_cmd {
ZIP_SOURCE_FREE /* cleanup and free resources */
};
typedef ssize_t (*zip_source_callback)(void *state, void *data,
size_t len, enum zip_source_cmd cmd);

188
ext/zip/lib/zip_close.c

@ -42,16 +42,26 @@
#include "zipint.h"
static int add_data(struct zip *, int, struct zip_dirent *, FILE *);
static int add_data(struct zip *, struct zip_source *, struct zip_dirent *,
FILE *);
static int add_data_comp(zip_source_callback, void *, struct zip_stat *,
FILE *, struct zip_error *);
static int add_data_uncomp(zip_source_callback, void *, struct zip_stat *,
FILE *, struct zip_error *);
static int add_data_uncomp(struct zip *, zip_source_callback, void *,
struct zip_stat *, FILE *);
static void ch_set_error(struct zip_error *, zip_source_callback, void *);
static int copy_data(FILE *, off_t, FILE *, struct zip_error *);
static int write_cdir(struct zip *, struct zip_cdir *, FILE *);
static int _zip_cdir_set_comment(struct zip_cdir *, struct zip *);
static int _zip_changed(struct zip *, int *);
static char *_zip_create_temp_output(struct zip *, FILE **);
static int _zip_torrentzip_cmp(const void *, const void *);
struct filelist {
int idx;
const char *name;
};
@ -65,7 +75,9 @@ zip_close(struct zip *za)
mode_t mask;
struct zip_cdir *cd;
struct zip_dirent de;
struct filelist *filelist;
int reopen_on_error;
int new_torrentzip;
reopen_on_error = 0;
@ -79,7 +91,7 @@ zip_close(struct zip *za)
/* don't create zip files with no entries */
if (survivors == 0) {
if (za->zn) {
if (za->zn && za->zp) {
if (remove(za->zn) != 0) {
_zip_error_set(&za->error, ZIP_ER_REMOVE, errno);
return -1;
@ -89,45 +101,85 @@ zip_close(struct zip *za)
return 0;
}
if ((cd=_zip_cdir_new(survivors, &za->error)) == NULL)
if ((filelist=(struct filelist *)malloc(sizeof(filelist[0])*survivors))
== NULL)
return -1;
if ((cd=_zip_cdir_new(survivors, &za->error)) == NULL) {
free(filelist);
return -1;
}
for (i=0; i<survivors; i++)
_zip_dirent_init(&cd->entry[i]);
/* archive comment is special for torrentzip */
if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) {
cd->comment = _zip_memdup(TORRENT_SIG "XXXXXXXX",
TORRENT_SIG_LEN + TORRENT_CRC_LEN,
&za->error);
if (cd->comment == NULL) {
_zip_cdir_free(cd);
free(filelist);
return -1;
}
cd->comment_len = TORRENT_SIG_LEN + TORRENT_CRC_LEN;
}
else if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, ZIP_FL_UNCHANGED) == 0) {
if (_zip_cdir_set_comment(cd, za) == -1) {
_zip_cdir_free(cd);
free(filelist);
return -1;
}
}
if ((temp=_zip_create_temp_output(za, &out)) == NULL) {
_zip_cdir_free(cd);
return -1;
}
error = 0;
/* create list of files with index into original archive */
for (i=j=0; i<za->nentry; i++) {
if (za->entry[i].state == ZIP_ST_DELETED)
continue;
filelist[j].idx = i;
filelist[j].name = zip_get_name(za, i, 0);
j++;
}
if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
qsort(filelist, survivors, sizeof(filelist[0]),
_zip_torrentzip_cmp);
new_torrentzip = (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 1
&& zip_get_archive_flag(za, ZIP_AFL_TORRENT,
ZIP_FL_UNCHANGED) == 0);
error = 0;
for (j=0; j<survivors; j++) {
i = filelist[j].idx;
/* create new local directory entry */
if (ZIP_ENTRY_DATA_CHANGED(za->entry+i)) {
if (ZIP_ENTRY_DATA_CHANGED(za->entry+i) || new_torrentzip) {
_zip_dirent_init(&de);
if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
_zip_dirent_torrent_normalize(&de);
/* use it as central directory entry */
memcpy(cd->entry+j, &de, sizeof(cd->entry[j]));
/* set/update file name */
if (za->entry[i].ch_filename == NULL) {
if (za->entry[i].state == ZIP_ST_REPLACED) {
de.filename = strdup(za->cdir->entry[i].filename);
de.filename_len = strlen(de.filename);
cd->entry[j].filename = za->cdir->entry[i].filename;
cd->entry[j].filename_len = de.filename_len;
}
else {
if (za->entry[i].state == ZIP_ST_ADDED) {
de.filename = strdup("-");
de.filename_len = 1;
cd->entry[j].filename = "-";
}
else {
de.filename = strdup(za->cdir->entry[i].filename);
de.filename_len = strlen(de.filename);
cd->entry[j].filename = za->cdir->entry[i].filename;
cd->entry[j].filename_len = de.filename_len;
}
}
@ -147,7 +199,7 @@ zip_close(struct zip *za)
de.crc = za->cdir->entry[i].crc;
de.comp_size = za->cdir->entry[i].comp_size;
de.uncomp_size = za->cdir->entry[i].uncomp_size;
/* de.bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR; */
de.bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR;
}
memcpy(cd->entry+j, za->cdir->entry+i, sizeof(cd->entry[j]));
}
@ -163,7 +215,8 @@ zip_close(struct zip *za)
cd->entry[j].filename_len = de.filename_len;
}
if (za->entry[i].ch_comment_len != -1) {
if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0
&& za->entry[i].ch_comment_len != -1) {
/* as the rest of cd entries, its malloc/free is done by za */
cd->entry[j].comment = za->entry[i].ch_comment;
cd->entry[j].comment_len = za->entry[i].ch_comment_len;
@ -171,8 +224,19 @@ zip_close(struct zip *za)
cd->entry[j].offset = ftello(out);
if (ZIP_ENTRY_DATA_CHANGED(za->entry+i)) {
if (add_data(za, i, &de, out) < 0) {
if (ZIP_ENTRY_DATA_CHANGED(za->entry+i) || new_torrentzip) {
struct zip_source *zs;
zs = NULL;
if (!ZIP_ENTRY_DATA_CHANGED(za->entry+i)) {
if ((zs=zip_source_zip(za, za, i, ZIP_FL_RECOMPRESS, 0, -1))
== NULL) {
error = 1;
break;
}
}
if (add_data(za, zs ? zs : za->entry[i].source, &de, out) < 0) {
error = 1;
break;
}
@ -195,13 +259,11 @@ zip_close(struct zip *za)
}
}
j++;
_zip_dirent_finalize(&de);
}
if (!error) {
if (_zip_cdir_write(cd, out, &za->error) < 0)
if (write_cdir(za, cd, out) < 0)
error = 1;
}
@ -252,15 +314,15 @@ zip_close(struct zip *za)
static int
add_data(struct zip *za, int idx, struct zip_dirent *de, FILE *ft)
add_data(struct zip *za, struct zip_source *zs, struct zip_dirent *de, FILE *ft)
{
off_t offstart, offend;
zip_source_callback cb;
void *ud;
struct zip_stat st;
cb = za->entry[idx].source->f;
ud = za->entry[idx].source->ud;
cb = zs->f;
ud = zs->ud;
if (cb(ud, &st, sizeof(st), ZIP_SOURCE_STAT) < (ssize_t)sizeof(st)) {
ch_set_error(&za->error, cb, ud);
@ -282,7 +344,7 @@ add_data(struct zip *za, int idx, struct zip_dirent *de, FILE *ft)
return -1;
}
else {
if (add_data_uncomp(cb, ud, &st, ft, &za->error) < 0)
if (add_data_uncomp(za, cb, ud, &st, ft) < 0)
return -1;
}
@ -298,12 +360,16 @@ add_data(struct zip *za, int idx, struct zip_dirent *de, FILE *ft)
return -1;
}
de->comp_method = st.comp_method;
de->last_mod = st.mtime;
de->comp_method = st.comp_method;
de->crc = st.crc;
de->uncomp_size = st.size;
de->comp_size = st.comp_size;
if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
_zip_dirent_torrent_normalize(de);
if (_zip_dirent_write(de, ft, 1, &za->error) < 0)
return -1;
@ -344,14 +410,15 @@ add_data_comp(zip_source_callback cb, void *ud, struct zip_stat *st,FILE *ft,
static int
add_data_uncomp(zip_source_callback cb, void *ud, struct zip_stat *st,
FILE *ft, struct zip_error *error)
add_data_uncomp(struct zip *za, zip_source_callback cb, void *ud,
struct zip_stat *st, FILE *ft)
{
char b1[BUFSIZE], b2[BUFSIZE];
int end, flush, ret;
ssize_t n;
size_t n2;
z_stream zstr;
int mem_level;
st->comp_method = ZIP_CM_DEFLATE;
st->comp_size = st->size = 0;
@ -363,8 +430,13 @@ add_data_uncomp(zip_source_callback cb, void *ud, struct zip_stat *st,
zstr.avail_in = 0;
zstr.avail_out = 0;
/* -15: undocumented feature of zlib to _not_ write a zlib header */
deflateInit2(&zstr, Z_BEST_COMPRESSION, Z_DEFLATED, -15, 9,
if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
mem_level = TORRENT_MEM_LEVEL;
else
mem_level = MAX_MEM_LEVEL;
/* -MAX_WBITS: undocumented feature of zlib to _not_ write a zlib header */
deflateInit2(&zstr, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, mem_level,
Z_DEFAULT_STRATEGY);
zstr.next_out = (Bytef *)b2;
@ -376,7 +448,7 @@ add_data_uncomp(zip_source_callback cb, void *ud, struct zip_stat *st,
while (!end) {
if (zstr.avail_in == 0 && !flush) {
if ((n=cb(ud, b1, sizeof(b1), ZIP_SOURCE_READ)) < 0) {
ch_set_error(error, cb, ud);
ch_set_error(&za->error, cb, ud);
deflateEnd(&zstr);
return -1;
}
@ -392,7 +464,7 @@ add_data_uncomp(zip_source_callback cb, void *ud, struct zip_stat *st,
ret = deflate(&zstr, flush);
if (ret != Z_OK && ret != Z_STREAM_END) {
_zip_error_set(error, ZIP_ER_ZLIB, ret);
_zip_error_set(&za->error, ZIP_ER_ZLIB, ret);
return -1;
}
@ -400,7 +472,7 @@ add_data_uncomp(zip_source_callback cb, void *ud, struct zip_stat *st,
n2 = sizeof(b2) - zstr.avail_out;
if (fwrite(b2, 1, n2, ft) != n2) {
_zip_error_set(error, ZIP_ER_WRITE, errno);
_zip_error_set(&za->error, ZIP_ER_WRITE, errno);
return -1;
}
@ -470,6 +542,44 @@ copy_data(FILE *fs, off_t len, FILE *ft, struct zip_error *error)
static int
write_cdir(struct zip *za, struct zip_cdir *cd, FILE *out)
{
off_t offset;
uLong crc;
char buf[TORRENT_CRC_LEN+1];
if (_zip_cdir_write(cd, out, &za->error) < 0)
return -1;
if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0)
return 0;
/* fix up torrentzip comment */
offset = ftello(out);
if (_zip_filerange_crc(out, cd->offset, cd->size, &crc, &za->error) < 0)
return -1;
snprintf(buf, sizeof(buf), "%08lX", (long)crc);
if (fseeko(out, offset-TORRENT_CRC_LEN, SEEK_SET) < 0) {
_zip_error_set(&za->error, ZIP_ER_SEEK, errno);
return -1;
}
if (fwrite(buf, TORRENT_CRC_LEN, 1, out) != 1) {
_zip_error_set(&za->error, ZIP_ER_WRITE, errno);
return -1;
}
return 0;
}
static int
_zip_cdir_set_comment(struct zip_cdir *dest, struct zip *src)
{
@ -501,7 +611,8 @@ _zip_changed(struct zip *za, int *survivorsp)
changed = survivors = 0;
if (za->ch_comment_len != -1)
if (za->ch_comment_len != -1
|| za->ch_flags != za->flags)
changed = 1;
for (i=0; i<za->nentry; i++) {
@ -550,3 +661,12 @@ _zip_create_temp_output(struct zip *za, FILE **outp)
*outp = tfp;
return temp;
}
static int
_zip_torrentzip_cmp(const void *a, const void *b)
{
return strcasecmp(((const struct filelist *)a)->name,
((const struct filelist *)b)->name);
}

59
ext/zip/lib/zip_dirent.c

@ -1,6 +1,6 @@
/*
zip_dirent.c -- read directory entry (local or central), clean dirent
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -318,6 +318,63 @@ _zip_dirent_read(struct zip_dirent *zde, FILE *fp,
/* _zip_dirent_torrent_normalize(de);
Set values suitable for torrentzip.
*/
void
_zip_dirent_torrent_normalize(struct zip_dirent *de)
{
static struct tm torrenttime;
static time_t last_mod = 0;
if (last_mod == 0) {
#ifdef HAVE_STRUCT_TM_TM_ZONE
time_t now;
struct tm *l;
#endif
torrenttime.tm_sec = 0;
torrenttime.tm_min = 32;
torrenttime.tm_hour = 23;
torrenttime.tm_mday = 24;
torrenttime.tm_mon = 11;
torrenttime.tm_year = 96;
torrenttime.tm_wday = 0;
torrenttime.tm_yday = 0;
torrenttime.tm_isdst = 0;
#ifdef HAVE_STRUCT_TM_TM_ZONE
time(&now);
l = localtime(&now);
torrenttime.tm_gmtoff = l->tm_gmtoff;
torrenttime.tm_zone = l->tm_zone;
#endif
last_mod = mktime(&torrenttime);
}
de->version_madeby = 0;
de->version_needed = 20; /* 2.0 */
de->bitflags = 2; /* maximum compression */
de->comp_method = ZIP_CM_DEFLATE;
de->last_mod = last_mod;
de->disk_number = 0;
de->int_attrib = 0;
de->ext_attrib = 0;
de->offset = 0;
free(de->extrafield);
de->extrafield = NULL;
de->extrafield_len = 0;
free(de->comment);
de->comment = NULL;
de->comment_len = 0;
}
/* _zip_dirent_write(zde, fp, localp, error):
Writes zip directory entry zde to file fp.

4
ext/zip/lib/zip_err_str.c

@ -1,6 +1,6 @@
/*
This file was generated automatically by make_zip_err_str.sh
from zip.h; make changes there.
This file was generated automatically by ./make_zip_err_str.sh
from ./zip.h; make changes there.
*/
#include "zipint.h"

71
ext/zip/lib/zip_filerange_crc.c

@ -0,0 +1,71 @@
/*
zip_filerange_crc.c -- compute CRC32 for a range of a file
Copyright (C) 2008 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <errno.h>
#include "zipint.h"
int
_zip_filerange_crc(FILE *fp, off_t start, off_t len, uLong *crcp,
struct zip_error *errp)
{
Bytef buf[BUFSIZE];
size_t n;
*crcp = crc32(0L, Z_NULL, 0);
if (fseeko(fp, start, SEEK_SET) != 0) {
_zip_error_set(errp, ZIP_ER_SEEK, errno);
return -1;
}
while (len > 0) {
n = len > BUFSIZE ? BUFSIZE : len;
if ((n=fread(buf, 1, n, fp)) <= 0) {
_zip_error_set(errp, ZIP_ER_READ, errno);
return -1;
}
*crcp = crc32(*crcp, buf, n);
len-= n;
}
return 0;
}

48
ext/zip/lib/zip_get_archive_flag.c

@ -0,0 +1,48 @@
/*
zip_get_archive_flag.c -- get archive global flag
Copyright (C) 2008 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN(int)
zip_get_archive_flag(struct zip *za, int flag, int flags)
{
int fl;
fl = (flags & ZIP_FL_UNCHANGED) ? za->flags : za->ch_flags;
return (fl & flag) ? 1 : 0;
}

23
ext/zip/lib/zip_open.c

@ -310,9 +310,8 @@ static void
_zip_check_torrentzip(struct zip *za)
{
uLong crc_got, crc_should;
char buf[8+1];
char *end;
Bytef buf[BUFSIZE];
unsigned int n, remain;
if (za->zp == NULL || za->cdir == NULL)
return;
@ -321,27 +320,17 @@ _zip_check_torrentzip(struct zip *za)
|| strncmp(za->cdir->comment, TORRENT_SIG, TORRENT_SIG_LEN) != 0)
return;
memcpy(buf, za->cdir->comment+TORRENT_SIG_LEN, 8);
buf[8] = '\0';
errno = 0;
crc_should = strtoul(za->cdir->comment+TORRENT_SIG_LEN, &end, 16);
crc_should = strtoul(buf, &end, 16);
if ((crc_should == UINT_MAX && errno != 0) || (end && *end))
return;
crc_got = crc32(0L, Z_NULL, 0);
if (fseek(za->zp, za->cdir->offset, SEEK_SET) != 0)
return;
remain = za->cdir->size;
while (remain > 0) {
n = remain > BUFSIZE ? BUFSIZE : remain;
if ((n=fread(buf, 1, n, za->zp)) <= 0)
if (_zip_filerange_crc(za->zp, za->cdir->offset, za->cdir->size,
&crc_got, NULL) < 0)
return;
crc_got = crc32(crc_got, buf, n);
remain -= n;
}
if (crc_got == crc_should)
za->flags |= ZIP_AFL_TORRENT;
}

20
ext/zip/lib/zip_rename.c

@ -1,6 +1,6 @@
/*
zip_rename.c -- rename file in zip archive
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -33,6 +33,8 @@
#include <string.h>
#include "zipint.h"
@ -40,7 +42,21 @@
ZIP_EXTERN(int)
zip_rename(struct zip *za, int idx, const char *name)
{
if (idx >= za->nentry || idx < 0) {
const char *old_name;
int old_is_dir, new_is_dir;
if (idx >= za->nentry || idx < 0 || name[0] == '\0') {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
if ((old_name=zip_get_name(za, idx, 0)) == NULL)
return -1;
new_is_dir = (name[strlen(name)-1] == '/');
old_is_dir = (old_name[strlen(old_name)-1] == '/');
if (new_is_dir != old_is_dir) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}

49
ext/zip/lib/zip_set_archive_flag.c

@ -0,0 +1,49 @@
/*
zip_get_archive_flag.c -- set archive global flag
Copyright (C) 2008 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The names of the authors may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "zipint.h"
ZIP_EXTERN(int)
zip_set_archive_flag(struct zip *za, int flag, int value)
{
if (value)
za->ch_flags |= flag;
else
za->ch_flags &= ~flag;
return 0;
}

17
ext/zip/lib/zip_source_file.c

@ -1,6 +1,6 @@
/*
zip_source_file.c -- create data source from file
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -43,9 +43,6 @@
ZIP_EXTERN(struct zip_source *)
zip_source_file(struct zip *za, const char *fname, off_t start, off_t len)
{
struct zip_source *zs;
FILE *fp;
if (za == NULL)
return NULL;
@ -54,15 +51,5 @@ zip_source_file(struct zip *za, const char *fname, off_t start, off_t len)
return NULL;
}
if ((fp=fopen(fname, "rb")) == NULL) {
_zip_error_set(&za->error, ZIP_ER_OPEN, errno);
return NULL;
}
if ((zs=zip_source_filep(za, fp, start, len)) == NULL) {
fclose(fp);
return NULL;
}
return zs;
return _zip_source_file_or_p(za, fname, NULL, start, len);
}

53
ext/zip/lib/zip_source_filep.c

@ -1,6 +1,6 @@
/*
zip_source_filep.c -- create data source from FILE *
Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -42,6 +42,7 @@
#include "zipint.h"
struct read_file {
char *fname; /* name of file to copy from */
FILE *f; /* file to copy from */
off_t off; /* start offset of */
off_t len; /* lengt of data to copy */
@ -57,9 +58,6 @@ static ssize_t read_file(void *state, void *data, size_t len,
ZIP_EXTERN(struct zip_source *)
zip_source_filep(struct zip *za, FILE *file, off_t start, off_t len)
{
struct read_file *f;
struct zip_source *zs;
if (za == NULL)
return NULL;
@ -68,11 +66,36 @@ zip_source_filep(struct zip *za, FILE *file, off_t start, off_t len)
return NULL;
}
return _zip_source_file_or_p(za, NULL, file, start, len);
}
struct zip_source *
_zip_source_file_or_p(struct zip *za, const char *fname, FILE *file,
off_t start, off_t len)
{
struct read_file *f;
struct zip_source *zs;
if (file == NULL && fname == NULL) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((f=(struct read_file *)malloc(sizeof(struct read_file))) == NULL) {
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
return NULL;
}
f->fname = NULL;
if (fname) {
if ((f->fname=strdup(fname)) == NULL) {
_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
free(f);
return NULL;
}
}
f->f = file;
f->off = start;
f->len = (len ? len : -1);
@ -99,6 +122,14 @@ read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd)
switch (cmd) {
case ZIP_SOURCE_OPEN:
if (z->fname) {
if ((z->f=fopen(z->fname, "rb")) == NULL) {
z->e[0] = ZIP_ER_OPEN;
z->e[1] = errno;
return -1;
}
}
if (fseeko(z->f, z->off, SEEK_SET) < 0) {
z->e[0] = ZIP_ER_SEEK;
z->e[1] = errno;
@ -125,17 +156,27 @@ read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd)
return i;
case ZIP_SOURCE_CLOSE:
if (z->fname) {
fclose(z->f);
z->f = NULL;
}
return 0;
case ZIP_SOURCE_STAT:
{
struct zip_stat *st;
struct stat fst;
int err;
if (len < sizeof(*st))
return -1;
if (fstat(fileno(z->f), &fst) != 0) {
if (z->f)
err = fstat(fileno(z->f), &fst);
else
err = stat(z->fname, &fst);
if (err != 0) {
z->e[0] = ZIP_ER_READ; /* best match */
z->e[1] = errno;
return -1;
@ -161,6 +202,8 @@ read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd)
return sizeof(int)*2;
case ZIP_SOURCE_FREE:
free(z->fname);
if (z->f)
fclose(z->f);
free(z);
return 0;

4
ext/zip/lib/zip_source_zip.c

@ -57,6 +57,8 @@ zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags,
struct zip_source *zs;
struct read_zip *p;
/* XXX: ZIP_FL_RECOMPRESS */
if (za == NULL)
return NULL;
@ -74,7 +76,7 @@ zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags,
if (len == 0)
len = -1;
if (start == 0 && len == -1)
if (start == 0 && len == -1 && (flags & ZIP_FL_RECOMPRESS) == 0)
flags |= ZIP_FL_COMPRESSED;
else
flags &= ~ZIP_FL_COMPRESSED;

6
ext/zip/lib/zip_unchange_archive.c

@ -1,6 +1,6 @@
/*
zip_unchange_archive.c -- undo global changes to ZIP archive
Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner
Copyright (C) 2006-2008 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@ -34,7 +34,7 @@
#include <stdlib.h>
#include "zip.h"
#include "zipint.h"
@ -46,5 +46,7 @@ zip_unchange_archive(struct zip *za)
za->ch_comment = NULL;
za->ch_comment_len = -1;
za->ch_flags = za->flags;
return 0;
}

9
ext/zip/lib/zipint.h

@ -67,6 +67,8 @@
#define DATADES_MAGIC "PK\7\8"
#define TORRENT_SIG "TORRENTZIPPED-"
#define TORRENT_SIG_LEN 14
#define TORRENT_CRC_LEN 8
#define TORRENT_MEM_LEVEL 8
#define CDENTRYSIZE 46u
#define LENTRYSIZE 30
#define MAXCOMLEN 65536
@ -208,6 +210,7 @@ extern const int _zip_err_type[];
int _zip_cdir_compute_crc(struct zip *, uLong *);
void _zip_cdir_free(struct zip_cdir *);
struct zip_cdir *_zip_cdir_new(int, struct zip_error *);
int _zip_cdir_write(struct zip_cdir *, FILE *, struct zip_error *);
@ -216,6 +219,7 @@ void _zip_dirent_finalize(struct zip_dirent *);
void _zip_dirent_init(struct zip_dirent *);
int _zip_dirent_read(struct zip_dirent *, FILE *,
unsigned char **, unsigned int, int, struct zip_error *);
void _zip_dirent_torrent_normalize(struct zip_dirent *);
int _zip_dirent_write(struct zip_dirent *, FILE *, int, struct zip_error *);
void _zip_entry_free(struct zip_entry *);
@ -233,6 +237,11 @@ const char *_zip_error_strerror(struct zip_error *);
int _zip_file_fillbuf(void *, size_t, struct zip_file *);
unsigned int _zip_file_get_offset(struct zip *, int);
int _zip_filerange_crc(FILE *, off_t, off_t, uLong *, struct zip_error *);
struct zip_source *_zip_source_file_or_p(struct zip *, const char *, FILE *,
off_t, off_t);
void _zip_free(struct zip *);
const char *_zip_get_name(struct zip *, int, int, struct zip_error *);
int _zip_local_header_read(struct zip *, int);

Loading…
Cancel
Save