change functions API overhaul:
- rename ZIP_CMD_INIT to ZIP_CMD_OPEN
- ZIP_CMD_CLOSE is called when reading is done
- add ZIP_CMD_FREE to free resources
- ZIP_CMD_STAT is called to retrieve meta info (time stamp, compression
method, sizes, crc)
- add ZIP_CMD_ERROR to return error codes
get rid of (now unused) zip_entry members ch_flags and ch_mtime
--HG--
branch : HEAD
diff --git a/TODO b/TODO
index 91506a9..84b7ba0 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,5 @@
------------------------------------------------ showstopper
+* zip_replace: remove flags argument? (currently unused)
* API cleanup
check function names (consistency, appropriateness)
file sizes, offsets: type big enough? (no, zip64)
@@ -13,6 +14,7 @@
* README
* set mtime for changed entries
------------------------------------------------ others
+* zip_replace_zip: allow rewinding
* API for (file and archive) comments
* fix warnings in zipcmp
* zipcmp: add option for file content comparison
diff --git a/lib/zip.h b/lib/zip.h
index e5dc65c..576f900 100644
--- a/lib/zip.h
+++ b/lib/zip.h
@@ -2,7 +2,7 @@
#define _HAD_ZIP_H
/*
- $NiH: zip.h,v 1.36 2004/04/14 14:01:22 dillo Exp $
+ $NiH: zip.h,v 1.37 2004/04/16 09:40:26 dillo Exp $
zip.h -- exported declarations.
Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -85,6 +85,7 @@
#define ZERR_NOZIP 19 /* N Not a zip archive */
#define ZERR_INTERNAL 20 /* N Internal error */
#define ZERR_INCONS 21 /* N Zip archive inconsistent */
+#define ZERR_REMOVE 22 /* S Can't remove file */
/* type of system error value */
@@ -110,10 +111,12 @@
enum zip_cmd {
- ZIP_CMD_INIT, /* prepare for reading */
+ ZIP_CMD_OPEN, /* prepare for reading */
ZIP_CMD_READ, /* read data */
- ZIP_CMD_CLOSE, /* close and cleanup */
- ZIP_CMD_STAT /* for compressed data */
+ ZIP_CMD_CLOSE, /* reading is done */
+ ZIP_CMD_STAT, /* get meta information */
+ ZIP_CMD_ERROR, /* get error information */
+ ZIP_CMD_FREE /* cleanup and free resources */
};
typedef ssize_t (*zip_read_func)(void *state, void *data,
diff --git a/lib/zip_close.c b/lib/zip_close.c
index 485f060..5f85f1a 100644
--- a/lib/zip_close.c
+++ b/lib/zip_close.c
@@ -1,5 +1,5 @@
/*
- $NiH: zip_close.c,v 1.40 2004/04/16 09:40:27 dillo Exp $
+ $NiH: zip_close.c,v 1.41 2004/04/19 11:49:12 dillo Exp $
zip_close.c -- close zip archive and update changes
Copyright (C) 1999, 2004 Dieter Baron and Thomas Klausner
@@ -47,10 +47,11 @@
#include "zipint.h"
static int add_data(struct zip *, int, struct zip_dirent *, FILE *);
-static int add_data_comp(zip_read_func, void *, struct zip_dirent *, FILE *,
+static int add_data_comp(zip_read_func, void *, struct zip_stat *, FILE *,
struct zip_error *);
-static int add_data_uncomp(zip_read_func, void *, struct zip_dirent *, FILE *,
+static int add_data_uncomp(zip_read_func, void *, struct zip_stat *, FILE *,
struct zip_error *);
+static void ch_set_error(struct zip_error *, zip_read_func, void *);
static int copy_data(FILE *, off_t, FILE *, struct zip_error *);
@@ -163,11 +164,11 @@
cd->entry[j].offset = ftell(tfp);
if (ZIP_ENTRY_DATA_CHANGED(za->entry+i)) {
- de.last_mod = za->entry[i].ch_mtime;
if (add_data(za, i, &de, tfp) < 0) {
error = -1;
break;
}
+ cd->entry[j].last_mod = de.last_mod;
cd->entry[j].comp_method = de.comp_method;
cd->entry[j].comp_size = de.comp_size;
cd->entry[j].uncomp_size = de.uncomp_size;
@@ -241,12 +242,18 @@
off_t offstart, offend;
zip_read_func rf;
void *ud;
+ struct zip_stat st;
rf = za->entry[idx].ch_func;
ud = za->entry[idx].ch_data;
- if (rf(ud, NULL, 0, ZIP_CMD_INIT) < 0) {
- /* XXX: set error */
+ if (rf(ud, &st, sizeof(st), ZIP_CMD_STAT) < sizeof(st)) {
+ ch_set_error(&za->error, rf, ud);
+ return -1;
+ }
+
+ if (rf(ud, NULL, 0, ZIP_CMD_OPEN) < 0) {
+ ch_set_error(&za->error, rf, ud);
return -1;
}
@@ -255,22 +262,19 @@
if (_zip_dirent_write(de, ft, 1, &za->error) < 0)
return -1;
- if (za->entry[idx].ch_flags & ZIP_CH_ISCOMP) {
- if (add_data_comp(rf, ud, de, ft, &za->error) < 0)
+ if (st.comp_method != ZIP_CM_STORE) {
+ if (add_data_comp(rf, ud, &st, ft, &za->error) < 0)
return -1;
}
else {
- if (add_data_uncomp(rf, ud, de, ft, &za->error) < 0)
+ if (add_data_uncomp(rf, ud, &st, ft, &za->error) < 0)
return -1;
}
-#if 0
- /* XXX: this is also called in _zip_free */
if (rf(ud, NULL, 0, ZIP_CMD_CLOSE) < 0) {
- /* XXX: set error */
+ ch_set_error(&za->error, rf, ud);
return -1;
}
-#endif
offend = ftell(ft);
@@ -279,6 +283,12 @@
return -1;
}
+ de->comp_method = st.comp_method;
+ de->last_mod = st.mtime;
+ de->crc = st.crc;
+ de->uncomp_size = st.size;
+ de->comp_size = st.comp_size;
+
if (_zip_dirent_write(de, ft, 1, &za->error) < 0)
return -1;
@@ -293,44 +303,33 @@
static int
-add_data_comp(zip_read_func rf, void *ud, struct zip_dirent *de, FILE *ft,
+add_data_comp(zip_read_func rf, void *ud, struct zip_stat *st,FILE *ft,
struct zip_error *error)
{
char buf[BUFSIZE];
ssize_t n;
- struct zip_stat st;
- if (rf(ud, &st, sizeof(st), ZIP_CMD_STAT) < 0) {
- /* XXX: set error */
- return -1;
- }
-
- de->comp_size = 0;
+ st->comp_size = 0;
while ((n=rf(ud, buf, sizeof(buf), ZIP_CMD_READ)) > 0) {
if (fwrite(buf, 1, n, ft) != n) {
_zip_error_set(error, ZERR_WRITE, errno);
return -1;
}
- de->comp_size += n;
+ st->comp_size += n;
}
if (n < 0) {
- /* XXX: set error */
+ ch_set_error(error, rf, ud);
return -1;
}
- de->comp_method = st.comp_method;
- /* de->last_mod = st.mtime; */
- de->crc = st.crc;
- de->uncomp_size = st.size;
-
return 0;
}
static int
-add_data_uncomp(zip_read_func rf, void *ud, struct zip_dirent *de, FILE *ft,
+add_data_uncomp(zip_read_func rf, void *ud, struct zip_stat *st, FILE *ft,
struct zip_error *error)
{
char b1[BUFSIZE], b2[BUFSIZE];
@@ -338,11 +337,9 @@
ssize_t n;
z_stream zstr;
- /* ZIP_CMD_STAT for mtime? */
-
- de->comp_method = ZIP_CM_DEFLATE;
- de->comp_size = de->uncomp_size = 0;
- de->crc = crc32(0, NULL, 0);
+ st->comp_method = ZIP_CM_DEFLATE;
+ st->comp_size = st->size = 0;
+ st->crc = crc32(0, NULL, 0);
zstr.zalloc = Z_NULL;
zstr.zfree = Z_NULL;
@@ -363,15 +360,15 @@
while (!end) {
if (zstr.avail_in == 0 && !flush) {
if ((n=rf(ud, b1, sizeof(b1), ZIP_CMD_READ)) < 0) {
- /* XXX: set error */
+ ch_set_error(error, rf, ud);
deflateEnd(&zstr);
return -1;
}
if (n > 0) {
zstr.avail_in = n;
zstr.next_in = b1;
- de->uncomp_size += n;
- de->crc = crc32(de->crc, b1, n);
+ st->size += n;
+ st->crc = crc32(st->crc, b1, n);
}
else
flush = Z_FINISH;
@@ -393,7 +390,7 @@
zstr.next_out = b2;
zstr.avail_out = sizeof(b2);
- de->comp_size += n;
+ st->comp_size += n;
}
if (ret == Z_STREAM_END) {
@@ -407,6 +404,23 @@
+static void
+ch_set_error(struct zip_error *error, zip_read_func rf, void *ud)
+{
+ int e[2];
+
+ if ((rf(ud, e, sizeof(e), ZIP_CMD_READ)) < sizeof(e)) {
+ error->zip_err = ZERR_INTERNAL;
+ error->sys_err = 0;
+ }
+ else {
+ error->zip_err = e[0];
+ error->sys_err = e[1];
+ }
+}
+
+
+
static int
copy_data(FILE *fs, off_t len, FILE *ft, struct zip_error *error)
{
diff --git a/lib/zip_free_entry.c b/lib/zip_free_entry.c
index 719864b..47b00e2 100644
--- a/lib/zip_free_entry.c
+++ b/lib/zip_free_entry.c
@@ -1,5 +1,5 @@
/*
- $NiH: zip_free_entry.c,v 1.10 2004/04/14 14:01:25 dillo Exp $
+ $NiH: zip_free_entry.c,v 1.11 2004/04/16 09:40:28 dillo Exp $
zip_free_entry.c -- free struct zip_entry
Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -52,7 +52,7 @@
free(ze->ch_filename);
if (ze->ch_func)
- ret = ze->ch_func(ze->ch_data, NULL, 0, ZIP_CMD_CLOSE);
+ ret = ze->ch_func(ze->ch_data, NULL, 0, ZIP_CMD_FREE);
return ret;
}
diff --git a/lib/zip_new_entry.c b/lib/zip_new_entry.c
index d8971ac..e35a423 100644
--- a/lib/zip_new_entry.c
+++ b/lib/zip_new_entry.c
@@ -1,5 +1,5 @@
/*
- $NiH: zip_new_entry.c,v 1.8 2004/04/14 14:01:26 dillo Exp $
+ $NiH: zip_new_entry.c,v 1.9 2004/04/16 09:40:29 dillo Exp $
zip_new_entry.c -- create and init struct zip_entry
Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -72,8 +72,6 @@
ze->ch_filename = NULL;
ze->ch_func = NULL;
ze->ch_data = NULL;
- ze->ch_flags = 0;
- ze->ch_mtime = -1;
if (zf)
zf->nentry++;
diff --git a/lib/zip_replace.c b/lib/zip_replace.c
index 7d2266d..553b11f 100644
--- a/lib/zip_replace.c
+++ b/lib/zip_replace.c
@@ -1,5 +1,5 @@
/*
- $NiH: zip_replace.c,v 1.12 2004/04/14 14:01:27 dillo Exp $
+ $NiH: zip_replace.c,v 1.13 2004/04/16 09:40:29 dillo Exp $
zip_replace.c -- replace file via callback function
Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -75,7 +75,6 @@
? ZIP_ST_ADDED : ZIP_ST_REPLACED);
zf->entry[idx].ch_func = fn;
zf->entry[idx].ch_data = state;
- zf->entry[idx].ch_flags = flags;
return 0;
}
diff --git a/lib/zip_replace_data.c b/lib/zip_replace_data.c
index 9ff8e2a..367b8cc 100644
--- a/lib/zip_replace_data.c
+++ b/lib/zip_replace_data.c
@@ -1,5 +1,5 @@
/*
- $NiH: zip_replace_data.c,v 1.13 2004/04/14 14:01:27 dillo Exp $
+ $NiH: zip_replace_data.c,v 1.14 2004/04/16 09:40:30 dillo Exp $
zip_replace_data.c -- replace file from buffer
Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -42,8 +42,8 @@
#include "zipint.h"
struct read_data {
- const char *buf, *data;
- off_t len;
+ const char *buf, *data, *end;
+ time_t mtime;
int freep;
};
@@ -78,8 +78,9 @@
}
f->data = data;
- f->len = len;
+ f->end = data+len;
f->freep = freep;
+ f->mtime = time(NULL);
return _zip_replace(zf, idx, name, read_data, f, 0);
}
@@ -97,24 +98,57 @@
buf = (char *)data;
switch (cmd) {
- case ZIP_CMD_INIT:
+ case ZIP_CMD_OPEN:
z->buf = z->data;
return 0;
case ZIP_CMD_READ:
- n = len > z->len ? z->len : len;
+ n = z->end - z->buf;
+ if (n > len)
+ n = len;
if (n < 0)
n = 0;
if (n) {
memcpy(buf, z->buf, n);
z->buf += n;
- z->len -= n;
}
return n;
case ZIP_CMD_CLOSE:
+ return 0;
+
+ case ZIP_CMD_STAT:
+ {
+ struct zip_stat *st;
+
+ if (len < sizeof(*st))
+ return -1;
+
+ st = (struct zip_stat *)data;
+
+ st->mtime = z->mtime;
+ st->crc = 0;
+ st->size = z->end - z->data;
+ st->comp_size = -1;
+ st->comp_method = ZIP_CM_STORE;
+
+ return sizeof(*st);
+ }
+
+ case ZIP_CMD_ERROR:
+ {
+ int *e;
+
+ if (len < sizeof(int)*2)
+ return -1;
+
+ e[0] = e[1] = 0;
+ }
+ return sizeof(int)*2;
+
+ case ZIP_CMD_FREE:
if (z->freep) {
free((void *)z->data);
z->data = NULL;
diff --git a/lib/zip_replace_filep.c b/lib/zip_replace_filep.c
index 95d7d0b..cfe193b 100644
--- a/lib/zip_replace_filep.c
+++ b/lib/zip_replace_filep.c
@@ -1,5 +1,5 @@
/*
- $NiH: zip_replace_filep.c,v 1.8 2004/04/14 14:01:27 dillo Exp $
+ $NiH: zip_replace_filep.c,v 1.9 2004/04/16 09:40:30 dillo Exp $
zip_replace_filep.c -- replace file from FILE*
Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -35,14 +35,21 @@
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "zip.h"
#include "zipint.h"
struct read_file {
- FILE *f;
- off_t off, len;
+ FILE *f; /* file to copy from */
+ off_t off; /* start offset of */
+ off_t len; /* lengt of data to copy */
+ off_t remain; /* bytes remaining to be copied */
+ int e[2]; /* error codes */
};
static int read_file(void *state, void *data, size_t len, enum zip_cmd cmd);
@@ -94,34 +101,74 @@
buf = (char *)data;
switch (cmd) {
- case ZIP_CMD_INIT:
+ case ZIP_CMD_OPEN:
if (fseeko(z->f, z->off, SEEK_SET) < 0) {
- /* XXX: zip_err = ZERR_SEEK; */
+ z->e[0] = ZERR_SEEK;
+ z->e[1] = errno;
return -1;
}
+ z->remain = z->len;
return 0;
case ZIP_CMD_READ:
- if (z->len != -1)
- n = len > z->len ? z->len : len;
+ if (z->remain != -1)
+ n = len > z->remain ? z->remain : len;
else
n = len;
if ((i=fread(buf, 1, n, z->f)) < 0) {
- /* XXX: zip_err = ZERR_READ; */
+ z->e[0] = ZERR_READ;
+ z->e[1] = errno;
return -1;
}
- if (z->len != -1)
- z->len -= i;
+ if (z->remain != -1)
+ z->remain -= i;
return i;
case ZIP_CMD_CLOSE:
- if (z->f) {
- fclose(z->f);
- z->f = NULL;
+ return 0;
+
+ case ZIP_CMD_STAT:
+ {
+ struct zip_stat *st;
+ struct stat fst;
+
+ if (len < sizeof(*st))
+ return -1;
+
+ st = (struct zip_stat *)data;
+
+ if (fstat(fileno(z->f), &fst) != 0) {
+ z->e[0] = ZERR_READ; /* best match */
+ z->e[1] = errno;
+ return -1;
+ }
+
+ st->mtime = fst.st_mtime;
+ st->crc = 0;
+ if (z->len != -1)
+ st->size = z->len;
+ else if ((fst.st_mode&S_IFMT) == S_IFREG)
+ st->size = fst.st_size;
+ else
+ st->size = -1;
+ st->comp_size = -1;
+ st->comp_method = ZIP_CM_STORE;
+
+ return sizeof(*st);
}
+
+ case ZIP_CMD_ERROR:
+ if (len < sizeof(int)*2)
+ return -1;
+
+ memcpy(data, z->e, sizeof(int)*2);
+ return sizeof(int)*2;
+
+ case ZIP_CMD_FREE:
+ fclose(z->f);
free(z);
return 0;
diff --git a/lib/zip_replace_zip.c b/lib/zip_replace_zip.c
index 2098467..fa0ceec 100644
--- a/lib/zip_replace_zip.c
+++ b/lib/zip_replace_zip.c
@@ -1,5 +1,5 @@
/*
- $NiH: zip_replace_zip.c,v 1.20 2004/04/17 19:15:30 dillo Exp $
+ $NiH: zip_replace_zip.c,v 1.21 2004/05/16 00:50:48 dillo Exp $
zip_replace_zip.c -- replace file from zip file
Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -36,6 +36,8 @@
#include <stdlib.h>
+#include <string.h>
+
#include "zip.h"
#include "zipint.h"
@@ -127,7 +129,7 @@
buf = (char *)data;
switch (cmd) {
- case ZIP_CMD_INIT:
+ case ZIP_CMD_OPEN:
for (n=0; n<z->off; n+= i) {
i = (z->off-n > sizeof(b) ? sizeof(b) : z->off-n);
if ((i=zip_fread(z->zf, b, i)) < 0) {
@@ -156,15 +158,31 @@
return i;
case ZIP_CMD_CLOSE:
- zip_fclose(z->zf);
- free(z);
return 0;
case ZIP_CMD_STAT:
if (len < sizeof(z->st))
return -1;
+ len = sizeof(z->st);
- memcpy(data, &z->st, sizeof(z->st));
+ memcpy(data, &z->st, len);
+ return len;
+
+ case ZIP_CMD_ERROR:
+ {
+ int *e;
+
+ if (len < sizeof(int)*2)
+ return -1;
+
+ e = (int *)data;
+ zip_file_get_error(z->zf, e, e+1);
+ }
+ return sizeof(int)*2;
+
+ case ZIP_CMD_FREE:
+ zip_fclose(z->zf);
+ free(z);
return 0;
default:
diff --git a/lib/zip_unchange_data.c b/lib/zip_unchange_data.c
index ab88ae0..b6a7b1a 100644
--- a/lib/zip_unchange_data.c
+++ b/lib/zip_unchange_data.c
@@ -1,5 +1,5 @@
/*
- $NiH: zip_unchange_data.c,v 1.10 2004/04/14 14:01:28 dillo Exp $
+ $NiH: zip_unchange_data.c,v 1.11 2004/04/16 09:40:31 dillo Exp $
zip_unchange_data.c -- undo helper function
Copyright (C) 1999, 2004 Dieter Baron and Thomas Klausner
@@ -51,8 +51,6 @@
ze->ch_func = NULL;
}
- ze->ch_flags = 0;
-
ze->state = ze->ch_filename ? ZIP_ST_RENAMED : ZIP_ST_UNCHANGED;
return ret;
diff --git a/lib/zipint.h b/lib/zipint.h
index 88a8f6a..3f60759 100644
--- a/lib/zipint.h
+++ b/lib/zipint.h
@@ -3,7 +3,7 @@
#define _HAD_ZIPINT_H
/*
- $NiH: zipint.h,v 1.24 2004/04/16 09:40:31 dillo Exp $
+ $NiH: zipint.h,v 1.25 2004/04/19 11:49:13 dillo Exp $
zipint.h -- internal declarations.
Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -146,9 +146,7 @@
enum zip_state state;
zip_read_func ch_func;
void *ch_data;
- int ch_flags; /* 1: data returned by ch_func is compressed */
char *ch_filename;
- time_t ch_mtime;
};