API cleanup (see ChangeLog) --HG-- branch : HEAD
diff --git a/ChangeLog b/ChangeLog index 0119f37..6fb2b82 100644 --- a/ChangeLog +++ b/ChangeLog
@@ -1,7 +1,31 @@ 2003-10-05 Dieter Baron <dillo@danbala.tuwien.ac.at> - * lib/zip.h: (struct zip_error) new struct. - * lib/zip.h: (struct zip, struct zip_file) add new member error. + * lib/zip.h, lib/zipint.h: Don't expose struct zip, struc + zip_file. + * lib/zip_open.c (zip_open): new argument errp, use it to store + error code. + * lib/zip_error_str.c (zip_error_str): new function. + * lib/zip_error_sys_type.c (zip_error_sys_type): new function. + * lib/zip_get_num_files.c (zip_get_num_files): new function. + * src/zipcmp.c (compare_zip): adapt to new API. + + * lib/zip.h, lib/zipint.h: Don't expose zip_err_str, rename to + _zip_err_str. Adapt users. + + * lib/zip_error.c(_zip_error_get): new function. + * lib/zip_get_error.c (zip_get_error): new function. + * lib/zip_file_get_error.c (zip_file_get_error): new function. + + * lib/zip.h (struct zip_stat): new struct. + * lib/zip_stat.c (zip_stat): new function. + * lib/zip_stat_index.c (zip_stat_index) new function. + + * lib/zip_error.c (_zip_error_set): new function. + * lib/zip_name_locate.c (zip_name_locate): set za->error if name + not found. + + * lib/zip.h: (struct zip_error): new struct. + * lib/zip.h: (struct zip, struct zip_file): add new member error. * lib/zip.h, lib/zipint.h, lib/make_zip_err_str.sh: add _zip_err_errno. * lib/zip_error.c (_zip_error_fini, _zip_error_init): new
diff --git a/TODO b/TODO index cfd0a7a..991e529 100644 --- a/TODO +++ b/TODO
@@ -1,19 +1,17 @@ ------------------------------------------------ showstopper * API cleanup check function names (consistency, appropriateness) - error handling: errno member in struct zip, struct zip_file - error handling in zip_open? file sizes, offsets: type big enough? - meta data: expose struct vs. accessor functions - don't expose struct zip, struct zip_file -* needed functions: - get error code from struct zip, struct zip_file - get nentries from zip -* documentation: zip_add*, zip_replace*, + don't expose struct zip, struct zip_file, struct zip_meta + clean up error handling and error code setting (get rid of zip_err) + zip_{add,replace}*: don't use struct zip_meta +* documentation: zip_add*, zip_replace*, zip_{,_file}get_error, + zip_error_sys_type, zip_get_num_files, zip_error_str [zip_free_meta, zip_meta_new] + zip_fopen, zip_name_locate: flags + zip_open: errp * regression tests * code review - ------------------------------------------------ others * fix warnings in zipcmp * zipcmp: add option for file content comparison
diff --git a/configure.ac b/configure.ac index 91a7e68..a3d31fb 100644 --- a/configure.ac +++ b/configure.ac
@@ -70,6 +70,7 @@ man/zip_name_locate.3:man/zip_name_locate.${MANFMT} man/zip_open.3:man/zip_open.${MANFMT} man/zip_rename.3:man/zip_rename.${MANFMT} + man/zip_stat.3:man/zip_stat.${MANFMT} man/zip_strerror.3:man/zip_strerror.${MANFMT} man/zip_unchange.3:man/zip_unchange.${MANFMT} man/zip_unchange_all.3:man/zip_unchange_all.${MANFMT}])
diff --git a/lib/Makefile.am b/lib/Makefile.am index 0fc78ee..53612c8 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am
@@ -14,8 +14,10 @@ zip_delete.c \ zip_err_str.c \ zip_error.c \ + zip_error_str.c \ zip_error_strerror.c \ zip_fclose.c \ + zip_file_get_error.c \ zip_file_strerror.c \ zip_fopen.c \ zip_fopen_index.c \ @@ -23,7 +25,9 @@ zip_free.c \ zip_free_entry.c \ zip_free_meta.c \ + zip_get_error.c \ zip_get_meta.c \ + zip_get_num_files.c \ zip_get_name.c \ zip_merge_meta.c \ zip_name_locate.c \ @@ -38,6 +42,8 @@ zip_replace_filep.c \ zip_replace_zip.c \ zip_set_name.c \ + zip_stat.c \ + zip_stat_index.c \ zip_strerror.c \ zip_unchange.c \ zip_unchange_all.c \
diff --git a/lib/make_zip_err_str.sh b/lib/make_zip_err_str.sh index 162a6d8..1c8ce0c 100755 --- a/lib/make_zip_err_str.sh +++ b/lib/make_zip_err_str.sh
@@ -22,7 +22,7 @@ -const char * const zip_err_str[] = { +const char * const _zip_err_str[] = { EOF sed -n '/^#define ZERR_/ s/.*\/\* . \([^*]*\) \*\// "\1",/p' "$1" \ @@ -31,7 +31,7 @@ cat <<EOF >> "$2.$$" || exit 1 }; -const int zip_nerr_str = sizeof(zip_err_str)/sizeof(zip_err_str[0]); +const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]); #define N ZIP_ET_NONE #define S ZIP_ET_SYS
diff --git a/lib/zip.h b/lib/zip.h index e36de4b..6853136 100644 --- a/lib/zip.h +++ b/lib/zip.h
@@ -2,7 +2,7 @@ #define _HAD_ZIP_H /* - $NiH: zip.h,v 1.33 2003/10/04 07:40:59 dillo Exp $ + $NiH: zip.h,v 1.34 2003/10/05 16:05:22 dillo Exp $ zip.h -- exported declarations. Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner @@ -52,6 +52,10 @@ #define ZIP_EXCL 2 #define ZIP_CHECKCONS 4 +/* flags for zip_name_locate */ +#define ZIP_NAME_NOCASE 1 +#define ZIP_NAME_NODIR 2 + int zip_err; /* global variable for errors returned by the low-level library */ @@ -78,70 +82,15 @@ #define ZERR_INTERNAL 20 /* N Internal error */ #define ZERR_INCONS 21 /* N Zip archive inconsistent */ -extern const char * const zip_err_str[]; -extern const int zip_nerr_str; +#define ZIP_ET_NONE 0 /* sys_err unused */ +#define ZIP_ET_SYS 1 /* sys_err is errno */ +#define ZIP_ET_ZIP 2 /* sys_err is zlib error code */ /* zip file */ typedef int (*zip_read_func)(void *state, void *data, int len, enum zip_cmd cmd); -struct zip_error { - int zip_err; /* libzip error code (ZERR_*) */ - int sys_err; /* copy of errno (E*) */ - char *str; /* string representation or NULL */ -}; - -struct zip { - char *zn; - FILE *zp; - struct zip_error error; - unsigned short comlen, changes; - unsigned int cd_size, cd_offset; - char *com; - int nentry, nentry_alloc; - struct zip_entry *entry; - int nfile, nfile_alloc; - struct zip_file **file; -}; - -/* file in zip file */ - -struct zip_file { - struct zip *zf; - char *name; - struct zip_error error; - int flags; /* -1: eof, >0: error */ - - int method; - /* position within zip file (fread/fwrite) */ - long fpos; - /* no of bytes left to read */ - unsigned long bytes_left; - /* no of bytes of compressed data left */ - unsigned long cbytes_left; - /* crc so far */ - unsigned long crc, crc_orig; - - char *buffer; - z_stream *zstr; -}; - -/* entry in zip file directory */ - -struct zip_entry { - struct zip_meta *meta; - char *fn; - char *fn_old; - unsigned int file_fnlen; - - enum zip_state state; - zip_read_func ch_func; - void *ch_data; - int ch_comp; /* 1: data returned by ch_func is compressed */ - struct zip_meta *ch_meta; -}; - struct zip_meta { unsigned short version_made, version_need, bitflags, comp_method, disknrstart, int_attr; @@ -151,6 +100,20 @@ unsigned char *ef, *lef, *fc; }; +struct zip_stat { + const char *name; /* name of the file */ + int index; /* index within archive */ + unsigned int crc; /* crc of file data */ + unsigned int size; /* size of file (uncompressed) */ + time_t mtime; /* modification time */ + unsigned int comp_size; /* size of file (compressed) */ + unsigned short comp_method; /* compression method used */ + /* unsigned short bitflags; */ +}; + +struct zip; +struct zip_file; + int zip_add(struct zip *, const char *, struct zip_meta *, @@ -165,17 +128,22 @@ struct zip *, int, int, int); int zip_close(struct zip *); int zip_delete(struct zip *, int); +int zip_error_str(char *, int, int, int); +int zip_error_sys_type(int); int zip_fclose(struct zip_file *); +void zip_file_get_error(struct zip_file *, int *, int *); const char *zip_file_strerror(struct zip_file *); struct zip_file *zip_fopen(struct zip *, const char *, int); struct zip_file *zip_fopen_index(struct zip *, int); int zip_fread(struct zip_file *, char *, int); void zip_free_meta(struct zip_meta *); +void zip_get_error(struct zip *, int *, int *); struct zip_meta *zip_get_meta(struct zip *, int); const char *zip_get_name(struct zip *, int); +int zip_get_num_files(struct zip *); int zip_name_locate(struct zip *, const char *, int); struct zip_meta *zip_new_meta(void); -struct zip *zip_open(const char *, int); +struct zip *zip_open(const char *, int, int *); int zip_rename(struct zip *, int, const char *); int zip_replace(struct zip *, int, const char *, struct zip_meta *, zip_read_func, void *, int); @@ -187,6 +155,8 @@ FILE *, int, int); int zip_replace_zip(struct zip *, int, const char *, struct zip_meta *, struct zip *, int, int, int); +int zip_stat(struct zip *, const char *, int, struct zip_stat *); +int zip_stat_index(struct zip *, int, struct zip_stat *); const char *zip_strerror(struct zip *); int zip_unchange(struct zip *, int); int zip_unchange_all(struct zip *);
diff --git a/lib/zip_error.c b/lib/zip_error.c index 5891321..2e28a8c 100644 --- a/lib/zip_error.c +++ b/lib/zip_error.c
@@ -1,5 +1,5 @@ /* - $NiH$ + $NiH: zip_error.c,v 1.1 2003/10/05 16:05:22 dillo Exp $ zip_error.c -- struct zip_error helper functions Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner @@ -51,10 +51,31 @@ +void +_zip_error_get(struct zip_error *err, int *zep, int *sep) +{ + if (zep) + *zep = err->zip_err; + /* XXX: only if valid? */ + if (sep) + *sep = err->sys_err; +} -void _zip_error_init(struct zip_error *err) + + +void +_zip_error_init(struct zip_error *err) { err->zip_err = 0; err->sys_err = 0; err->str = NULL; } + + + +void +_zip_error_set(struct zip_error *err, int ze, int se) +{ + err->zip_err = ze; + err->sys_err = se; +}
diff --git a/lib/zip_error_str.c b/lib/zip_error_str.c new file mode 100644 index 0000000..548b2c0 --- /dev/null +++ b/lib/zip_error_str.c
@@ -0,0 +1,73 @@ +/* + $NiH$ + + zip_error_str.c -- get string representation of zip error code + Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at <nih@giga.or.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 <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "zip.h" +#include "zipint.h" + + + +int +zip_error_str(char *buf, int len, int ze, int se) +{ + const char *zs, *ss; + + if (ze < 0 || ze >= _zip_nerr_str) + return snprintf(buf, len, "Unknown error %d", ze); + + zs = _zip_err_str[ze]; + + switch (_zip_err_type[ze]) { + case ZIP_ET_SYS: + ss = strerror(se); + break; + + case ZIP_ET_ZIP: + ss = zError(se); + break; + + default: + ss = NULL; + } + + return snprintf(buf, len, "%s%s%s", + zs, (ss ? ": " : ""), (ss ? ss : "")); +}
diff --git a/lib/zip_error_strerror.c b/lib/zip_error_strerror.c index 7e8791a..fae7c1c 100644 --- a/lib/zip_error_strerror.c +++ b/lib/zip_error_strerror.c
@@ -1,5 +1,5 @@ /* - $NiH$ + $NiH: zip_error_strerror.c,v 1.1 2003/10/05 16:05:22 dillo Exp $ zip_error_sterror.c -- get string representation of struct zip_error Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner @@ -48,28 +48,45 @@ const char * _zip_error_strerror(struct zip_error *err) { + const char *zs, *ss; + char buf[128], *s; + _zip_error_fini(err); - if (err->zip_err < 0 || err->zip_err >= zip_nerr_str) { - /* XXX */ - asprintf(&err->str, "Unknown error %d", err->zip_err); - return err->str; + if (err->zip_err < 0 || err->zip_err >= _zip_nerr_str) { + sprintf(buf, "Unknown error %d", err->zip_err); + zs = NULL; + ss = buf; + } + else { + zs = _zip_err_str[err->zip_err]; + + switch (_zip_err_type[err->zip_err]) { + case ZIP_ET_SYS: + ss = strerror(err->sys_err); + break; + + case ZIP_ET_ZIP: + ss = zError(err->sys_err); + break; + + default: + ss = NULL; + } } - switch (_zip_err_type[err->zip_err]) { - case ZIP_ET_SYS: - /* XXX */ - asprintf(&err->str, "%s: %s", - zip_err_str[err->zip_err], strerror(err->sys_err)); - return err->str; + if (ss == NULL) + return zs; + else { + if ((s=malloc(strlen(ss) + (zs ? strlen(zs)+2 : 0) + 1)) == NULL) + return _zip_err_str[ZERR_MEMORY]; + + sprintf(s, "%s%s%s", + (zs ? zs : ""), + (zs ? ": " : ""), + ss); + err->str = s; - case ZIP_ET_ZIP: - /* XXX */ - asprintf(&err->str, "%s: %s", - zip_err_str[err->zip_err], zError(err->sys_err)); - return err->str; - - default: - return zip_err_str[err->zip_err]; + return ss; } }
diff --git a/lib/zip_error_sys_type.c b/lib/zip_error_sys_type.c new file mode 100644 index 0000000..7c1c899 --- /dev/null +++ b/lib/zip_error_sys_type.c
@@ -0,0 +1,50 @@ +/* + $NiH$ + + zip_error_sys_type.c -- return type of system error code + Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at <nih@giga.or.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 "zip.h" +#include "zipint.h" + + + +int +zip_error_sys_type(int ze) +{ + if (ze < 0 || ze >= _zip_nerr_str) + return 0; + + return _zip_err_type[ze]; +}
diff --git a/lib/zip_file_get_error.c b/lib/zip_file_get_error.c new file mode 100644 index 0000000..f9f36a6 --- /dev/null +++ b/lib/zip_file_get_error.c
@@ -0,0 +1,47 @@ +/* + $NiH$ + + zip_file_get_error.c -- get zip file error + Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at <nih@giga.or.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 "zip.h" +#include "zipint.h" + + + +void +zip_file_get_error(struct zip_file *zf, int *zep, int *sep) +{ + _zip_error_get(&zf->error, zep, sep); +}
diff --git a/lib/zip_get_error.c b/lib/zip_get_error.c new file mode 100644 index 0000000..5545565 --- /dev/null +++ b/lib/zip_get_error.c
@@ -0,0 +1,47 @@ +/* + $NiH$ + + zip_get_error.c -- get zip error + Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at <nih@giga.or.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 "zip.h" +#include "zipint.h" + + + +void +zip_get_error(struct zip *za, int *zep, int *sep) +{ + _zip_error_get(&za->error, zep, sep); +}
diff --git a/lib/zip_get_num_files.c b/lib/zip_get_num_files.c new file mode 100644 index 0000000..9b399cc --- /dev/null +++ b/lib/zip_get_num_files.c
@@ -0,0 +1,47 @@ +/* + $NiH$ + + zip_get_num_files.c -- get number of files in archive + Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at <nih@giga.or.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 "zip.h" +#include "zipint.h" + + + +int +zip_get_num_files(struct zip *za) +{ + return za->nentry; +}
diff --git a/lib/zip_name_locate.c b/lib/zip_name_locate.c index 32f6ebe..eb7c9a9 100644 --- a/lib/zip_name_locate.c +++ b/lib/zip_name_locate.c
@@ -1,5 +1,5 @@ /* - $NiH: zip_name_locate.c,v 1.7 2003/10/01 09:51:00 dillo Exp $ + $NiH: zip_name_locate.c,v 1.8 2003/10/02 14:13:30 dillo Exp $ zip_name_locate.c -- get index by name Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner @@ -43,13 +43,27 @@ int -zip_name_locate(struct zip *zf, const char *fname, int case_sens) +zip_name_locate(struct zip *za, const char *fname, int flags) { + int (*cmp)(); + const char *fn; int i; - for (i=0; i<zf->nentry; i++) - if ((case_sens ? strcmp : strcasecmp)(fname, zf->entry[i].fn) == 0) - return i; + cmp = (flags & ZIP_NAME_NOCASE) ? strcmp : strcasecmp; + for (i=0; i<za->nentry; i++) { + if (flags & ZIP_NAME_NODIR) { + /* XXX: handle '\' */ + if ((fn=strrchr(za->entry[i].fn, '/')) == NULL) + fn = za->entry[i].fn; + } + else + fn = za->entry[i].fn; + + if (cmp(fname, fn) == 0) + return i; + } + + _zip_error_set(&za->error, ZERR_NOENT, 0); return -1; }
diff --git a/lib/zip_open.c b/lib/zip_open.c index ee89a79..3323e11 100644 --- a/lib/zip_open.c +++ b/lib/zip_open.c
@@ -1,5 +1,5 @@ /* - $NiH: zip_open.c,v 1.15 2003/10/01 09:51:00 dillo Exp $ + $NiH: zip_open.c,v 1.16 2003/10/02 14:13:31 dillo Exp $ zip_open.c -- open zip file Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner @@ -46,6 +46,7 @@ #include "zip.h" #include "zipint.h" +static void set_error(int *errp, int err); static struct zip *_zip_readcdir(FILE *fp, unsigned char *buf, unsigned char *eocd, int buflen); static int _zip_read2(unsigned char **a); @@ -69,7 +70,7 @@ zipfile struct, or NULL if unsuccessful, setting zip_err. */ struct zip * -zip_open(const char *fn, int flags) +zip_open(const char *fn, int flags, int *errp) { FILE *fp; unsigned char *buf, *match; @@ -79,32 +80,34 @@ struct stat st; if (fn == NULL) { - zip_err = ZERR_INVAL; + set_error(errp, ZERR_INVAL); return NULL; } if (stat(fn, &st) != 0) { if (flags & ZIP_CREATE) { cdir = _zip_new(); + /* XXX: check cdir != NULL */ cdir->zn = strdup(fn); if (!cdir->zn) { - zip_err = ZERR_MEMORY; + /* XXX: free cdir */ + set_error(errp, ZERR_MEMORY); return NULL; } return cdir; } else { - zip_err = ZERR_NOENT; + set_error(errp, ZERR_NOENT); return NULL; } } else if ((flags & ZIP_EXCL)) { - zip_err = ZERR_EXISTS; + set_error(errp, ZERR_EXISTS); return NULL; } /* ZIP_CREATE gets ignored if file exists and not ZIP_EXCL, just like open() */ if ((fp=fopen(fn, "rb"))==NULL) { - zip_err = ZERR_OPEN; + set_error(errp, ZERR_OPEN); return NULL; } @@ -114,14 +117,16 @@ i = fseek(fp, -(len < BUFSIZE ? len : BUFSIZE), SEEK_END); if (i == -1 && errno != EFBIG) { /* seek before start of file on my machine */ - zip_err = ZERR_SEEK; + set_error(errp, ZERR_SEEK); fclose(fp); return NULL; } + /* XXX: why not allocate statically? */ buf = (unsigned char *)malloc(BUFSIZE); if (!buf) { - zip_err = ZERR_MEMORY; + set_error(errp, ZERR_MEMORY); + fclose(fp); return NULL; } @@ -129,7 +134,7 @@ buflen = fread(buf, 1, BUFSIZE, fp); if (ferror(fp)) { - zip_err = ZERR_READ; + set_error(errp, ZERR_READ); free(buf); fclose(fp); return NULL; @@ -170,7 +175,7 @@ if (best < 0) { /* no consistent eocd found */ - zip_err = ZERR_NOZIP; + set_error(errp, ZERR_NOZIP); free(buf); _zip_free(cdir); fclose(fp); @@ -181,7 +186,9 @@ cdir->zn = strdup(fn); if (!cdir->zn) { - zip_err = ZERR_MEMORY; + set_error(errp, ZERR_MEMORY); + _zip_free(cdir); + fclose(fp); return NULL; } @@ -192,6 +199,15 @@ +static void +set_error(int *errp, int err) +{ + if (errp) + *errp = err; +} + + + /* _zip_readcdir: tries to find a valid end-of-central-directory at the beginning of buf, and then the corresponding central directory entries.
diff --git a/lib/zip_stat.c b/lib/zip_stat.c new file mode 100644 index 0000000..44a1113 --- /dev/null +++ b/lib/zip_stat.c
@@ -0,0 +1,52 @@ +/* + $NiH$ + + zip_stat.c -- get information about file by name + Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at <nih@giga.or.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 "zip.h" +#include "zipint.h" + + + +int +zip_stat(struct zip *za, const char *fname, int flags, struct zip_stat *st) +{ + int idx; + + if ((idx=zip_name_locate(za, fname, flags)) < 0) + return -1; + + return zip_stat_index(za, idx, st); +}
diff --git a/lib/zip_stat_index.c b/lib/zip_stat_index.c new file mode 100644 index 0000000..06bda6e --- /dev/null +++ b/lib/zip_stat_index.c
@@ -0,0 +1,61 @@ +/* + $NiH$ + + zip_stat_index.c -- get information about file by index + Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at <nih@giga.or.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 "zip.h" +#include "zipint.h" + + + +int +zip_stat_index(struct zip *za, int index, struct zip_stat *st) +{ + if (index < 0 || index >= za->nentry) { + _zip_error_set(&za->error, ZERR_INVAL, 0); + return -1; + } + + st->name = za->entry[index].fn; + st->index = index; + st->crc = za->entry[index].meta->crc; + st->size = za->entry[index].meta->uncomp_size; + st->mtime = za->entry[index].meta->last_mod; + st->comp_size = za->entry[index].meta->comp_size; + st->comp_method = za->entry[index].meta->comp_method; + /* st->bitflags = za->entry[index].meta->bitflags; */ + + return 0; +}
diff --git a/lib/zipint.h b/lib/zipint.h index 37ea3a9..69fb693 100644 --- a/lib/zipint.h +++ b/lib/zipint.h
@@ -2,7 +2,7 @@ #define _HAD_ZIPINT_H /* - $NiH: zipint.h,v 1.18 2003/10/02 14:13:33 dillo Exp $ + $NiH: zipint.h,v 1.19 2003/10/05 16:05:22 dillo Exp $ zipint.h -- internal declarations. Copyright (C) 1999, 2003 Dieter Baron and Thomas Klausner @@ -48,8 +48,68 @@ #define CDENTRYSIZE 46 #define LENTRYSIZE 30 -enum { ZIP_ET_NONE, ZIP_ET_SYS, ZIP_ET_ZIP }; + +struct zip_error { + int zip_err; /* libzip error code (ZERR_*) */ + int sys_err; /* copy of errno (E*) or zlib error code */ + char *str; /* string representation or NULL */ +}; + +struct zip { + char *zn; + FILE *zp; + struct zip_error error; + unsigned short comlen, changes; + unsigned int cd_size, cd_offset; + char *com; + int nentry, nentry_alloc; + struct zip_entry *entry; + int nfile, nfile_alloc; + struct zip_file **file; +}; + +/* file in zip file */ + +struct zip_file { + struct zip *zf; + char *name; + struct zip_error error; + int flags; /* -1: eof, >0: error */ + + int method; + /* position within zip file (fread/fwrite) */ + long fpos; + /* no of bytes left to read */ + unsigned long bytes_left; + /* no of bytes of compressed data left */ + unsigned long cbytes_left; + /* crc so far */ + unsigned long crc, crc_orig; + + char *buffer; + z_stream *zstr; +}; + +/* entry in zip file directory */ + +struct zip_entry { + struct zip_meta *meta; + char *fn; + char *fn_old; + unsigned int file_fnlen; + + enum zip_state state; + zip_read_func ch_func; + void *ch_data; + int ch_comp; /* 1: data returned by ch_func is compressed */ + struct zip_meta *ch_meta; +}; + + + +extern const char * const _zip_err_str[]; +extern const int _zip_nerr_str; extern const int _zip_err_type[]; @@ -57,7 +117,9 @@ void _zip_entry_init(struct zip *, int); const char *_zip_error_strerror(struct zip_error *); void _zip_error_fini(struct zip_error *); +void _zip_error_get(struct zip_error *, int *, int *); void _zip_error_init(struct zip_error *); +void _zip_error_set(struct zip_error *, int, int); int _zip_file_fillbuf(char *, int, struct zip_file *); int _zip_free(struct zip *); int _zip_free_entry(struct zip_entry *);
diff --git a/man/Makefile.am b/man/Makefile.am index 4225793..c6a792a 100644 --- a/man/Makefile.am +++ b/man/Makefile.am
@@ -14,6 +14,8 @@ zip_name_locate.3 \ zip_open.3 \ zip_rename.3 \ + zip_stat.3 \ + zip_stat_index.3 \ zip_strerror.3 \ zip_unchange.3 \ zip_unchange_all.3 @@ -25,6 +27,8 @@ link-man3: install-man3 -rm -f ${man3dir}/zip_fopen_index.3 ${LN} ${man3dir}/zip_fopen.3 ${man3dir}/zip_fopen_index.3 + -rm -f ${man3dir}/zip_stat_index.3 + ${LN} ${man3dir}/zip_stat.3 ${man3dir}/zip_stat_index.3 MANDOC=${MAN1:.1=.mdoc} ${MAN3:.3=.mdoc} MAN=${MANDOC:.mdoc=.man}
diff --git a/man/zip_stat.mdoc b/man/zip_stat.mdoc new file mode 100644 index 0000000..795d6be --- /dev/null +++ b/man/zip_stat.mdoc
@@ -0,0 +1,101 @@ +.\" $NiH$ +.\" +.\" zip_stat.mdoc -- get information about file +.\" Copyright (C) 2003 Dieter Baron and Thomas Klausner +.\" +.\" This file is part of libzip, a library to manipulate ZIP archives. +.\" The authors can be contacted at <nih@giga.or.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. +.\" +.Dd October 3, 2003 +.Dt ZIP_STAT 3 +.Os +.Sh NAME +.Nm zip_stat , +.Nm zip_stat_index +.Nd get information about file +.Sh LIBRARY +libzip (-lzip) +.Sh SYNOPSIS +.In zip.h +.Ft int +.Fn zip_stat "struct zip *archive" "const char *fname" "int case_sens" "struct zip_stat *sb" +.Ft int +.Fn zip_stat_index "struct zip *archive" "int index" "struct zip_stat *sb" +.Sh DESCRIPTION +The +.Fn zip_stat +function obtains information about the file named +.Ar fname +in +.Ar archive . +The +.Ar flags +argument specifies how the name lookup should be done. +Its values are described in +.Xr zip_name_locate 3 . +.Pp +The +.Fn zip_stat_index +function obtains information about the file at position +.Ar index . +.Pp +The +.Ar sb +argument is a pointer to a +.Ft struct zip_stat +(shown below), into which information about the file is placed. +.Bd -literal +struct zip_stat { + const char *name; /* name of the file */ + int index; /* index within archive */ + unsigned int crc; /* crc of file data */ + unsigned int size; /* size of file (uncompressed) */ + time_t mtime; /* modification time */ + unsigned int comp_size; /* size of file (compressed) */ + unsigned short comp_method; /* compression method used */ +}; +.Sh RETURN VALUES +Upon successful completion 0 is returned. +Otherwise, \-1 is returned and the error information in +.Ar archive +is set to indicate the error. +.Sh ERRORS +The function +.Fn zip_stat +can fail for any of the errors specified for the routine +.Xr zip_name_locate 3 . +.Pp +The function +.Fn zip_stata_index +fails and sets the error information to +.Er ZERR_INVAL +if +.Ar index +is invalid. +.Sh SEE ALSO +.Xr zip_name_locate 3
diff --git a/src/zipcmp.c b/src/zipcmp.c index 1d9e6c7..3e9a0fb 100644 --- a/src/zipcmp.c +++ b/src/zipcmp.c
@@ -1,5 +1,5 @@ /* - $NiH: zipcmp.c,v 1.4 2003/10/02 14:13:37 dillo Exp $ + $NiH: zipcmp.c,v 1.5 2003/10/03 23:54:32 dillo Exp $ cmpzip.c -- compare zip files Copyright (C) 2003 Dieter Baron and Thomas Klausner @@ -35,6 +35,7 @@ +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -141,18 +142,22 @@ compare_zip(const char *zn[], int verbose) { struct zip *z; + struct zip_stat st; struct entry *e[2]; int n[2]; int i, j; + int err; + char errstr[1024]; for (i=0; i<2; i++) { - if ((z=zip_open(zn[i], ZIP_CHECKCONS)) == NULL) { + if ((z=zip_open(zn[i], ZIP_CHECKCONS, &err)) == NULL) { + zip_error_str(errstr, sizeof(errstr), err, errno); fprintf(stderr, "%s: cannot open zip file `%s': %s\n", - prg, zn[i], zip_err_str[zip_err]); + prg, zn[i], errstr); return -1; } - n[i] = z->nentry; + n[i] = zip_get_num_files(z); if ((e[i]=malloc(sizeof(*e[i]) * n[i])) == NULL) { fprintf(stderr, "%s: malloc failure\n", prg); @@ -160,9 +165,10 @@ } for (j=0; j<n[i]; j++) { - e[i][j].name = strdup(z->entry[j].fn); - e[i][j].size = z->entry[j].meta->uncomp_size; - e[i][j].crc = z->entry[j].meta->crc; + zip_stat_index(z, i, &st); + e[i][j].name = strdup(st.name); + e[i][j].size = st.size; + e[i][j].crc = st.crc; } zip_close(z);