Merge 0.9.1 branch.

--HG--
branch : HEAD
diff --git a/.hgignore b/.hgignore
index d23e0d4..ea54d5c 100644
--- a/.hgignore
+++ b/.hgignore
@@ -9,11 +9,13 @@
 \.pc$
 ^aclocal.m4$
 ^autom4te\.cache/
+^build
 ^config\.(h|status|log|h\.in)$
 ^configure$
 ^libtool$
 ^stamp-h1$
 ^lib/zip_err_str\.c$
+^lib/zipconf\.h$
 ^man/.*\.html$
 ^regress/add_dir$
 ^regress/add_from_buffer$
diff --git a/.hgtags b/.hgtags
index 6cae67d..7f5430b 100644
--- a/.hgtags
+++ b/.hgtags
@@ -1,3 +1,3 @@
 e5ac19fb4c5bea4a42ca62c10f6499b7f25538bc rel-0-8
-8f9595fbd779787cd45ce14081cd0a81fd7dc9c9 rel-0-9-1
+1c04fdb0f57bbb8e3823eb52b541ca2d8a348fde rel-0-9
 305c067cba3a04d11e95c7cd1e0ae55d662620ee rel-0-9-1
diff --git a/CMakeLists.txt b/CMakeLists.txt
old mode 100644
new mode 100755
index 5867845..f1cc65e
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,3 @@
-# $NiH: CMakeLists.txt,v 1.1 2007/03/04 10:35:17 wiz Exp $
-
 # XXX: TODO
 # 1. pkgconfig file not yet built.
 # 2. installation not tested.
@@ -7,11 +5,14 @@
 # 4. distribution tarball not checked for unwanted/missing content.
 # 5. create usable libtool .la file
 
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
 PROJECT(libzip C)
 
 INCLUDE(CheckFunctionExists)
 INCLUDE(CheckIncludeFiles)
 INCLUDE(CheckSymbolExists)
+INCLUDE(CheckTypeSize)
 
 SET(PACKAGE "libzip")
 SET(PACKAGE_NAME ${PACKAGE})
@@ -34,7 +35,23 @@
 CHECK_FUNCTION_EXISTS(mkstemp HAVE_MKSTEMP)
 CHECK_INCLUDE_FILES(unistd.h HAVE_UNISTD_H)
 
-INCLUDE(FindZLIB)
+CHECK_INCLUDE_FILES(sys/types.h HAVE_SYS_TYPES_H_LIBZIP)
+CHECK_INCLUDE_FILES(inttypes.h HAVE_INTTYPES_H_LIBZIP)
+CHECK_TYPE_SIZE(int8_t INT8_T_LIBZIP)
+CHECK_TYPE_SIZE(uint8_t UINT8_T_LIBZIP)
+CHECK_TYPE_SIZE(int16_t INT16_T_LIBZIP)
+CHECK_TYPE_SIZE(uint16_t UINT16_T_LIBZIP)
+CHECK_TYPE_SIZE(int32_t INT32_T_LIBZIP)
+CHECK_TYPE_SIZE(uint32_t UINT32_T_LIBZIP)
+CHECK_TYPE_SIZE(int64_t INT64_T_LIBZIP)
+CHECK_TYPE_SIZE(uint64_t UINT64_T_LIBZIP)
+CHECK_TYPE_SIZE(short SHORT_LIBZIP)
+CHECK_TYPE_SIZE(int INT_LIBZIP)
+CHECK_TYPE_SIZE(long LONG_LIBZIP)
+CHECK_TYPE_SIZE("long long" LONGLONG_LIBZIP)
+
+FIND_PACKAGE(ZLIB REQUIRED)
+INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
 CHECK_SYMBOL_EXISTS(ZEXPORT zlib.h HAVE_ZEXPORT)
 IF(NOT HAVE_ZEXPORT)
   MESSAGE(FATAL_ERROR "-- ZLIB version too old, please install at least v1.1.2")
@@ -53,8 +70,7 @@
 SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "library for manipulating zip archives")
 SET(CPACK_PACKAGE_VENDOR "Dieter Baron <dillo@giga.or.at> and Thomas Klausner <tk@giga.or.at>")
 SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
-# XXX: provide a license file
-#SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING")
+SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
 SET(CPACK_PACKAGE_VERSION_MAJOR ${PACKAGE_VERSION_MAJOR})
 SET(CPACK_PACKAGE_VERSION_MINOR ${PACKAGE_VERSION_MINOR})
 SET(CPACK_PACKAGE_VERSION_PATCH ${PACKAGE_VERSION_PATCH})
@@ -82,8 +98,6 @@
   "config.h$"
   "config.log$"
   "config.status$"
-  "dccsend$"
-  "dccserver$"
   "html$"
   "install_manifest.txt$"
   "stamp-h1$"
@@ -97,3 +111,7 @@
 # write out config file
 CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/cmake-config.h.in
   ${CMAKE_CURRENT_BINARY_DIR}/config.h)
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/cmake-zipconf.h.in
+  ${CMAKE_CURRENT_BINARY_DIR}/zipconf.h)
+
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/zipconf.h DESTINATION lib/libzip/include)
diff --git a/Makefile.am b/Makefile.am
index a25b86c..0a3e695 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,5 +9,6 @@
 EXTRA_DIST=	LICENSE \
 		CMakeLists.txt \
 		cmake-config.h.in \
+		cmake-zipconf.h.in \
 		libzip.pc.in \
 		libzip-uninstalled.pc.in
diff --git a/TODO b/TODO
index fb44f99..94608eb 100644
--- a/TODO
+++ b/TODO
@@ -1,14 +1,18 @@
-+ [portability] no off_t in API
+! zip_fdopen: upon error, fd should remain unchanged
+! [compat] test calls against old API
 + [portability] use _setmode(_fileno(fp), _O_BINARY); where present
++ [bug] fix permissions of new file to match old one
++ [bug] _zip_checkcons return value can overflow
 + [bug] _zip_u2d_time: handle localtime(3) failure
 + [bug] missing -Wl,-R in pkg-config file
-+ [bug] check/cleanup flags bit 3 (streaming) support
-- [feature] zip_fdopen (read zip from file descriptor), ZIP_AFL_RDONLY
-- [feature] Windows support: (paritally fixed?)
++ [cleanup] use zip_*int*_t internally
++ [cleanup] don't make zip_source_zip go through zip_fread
++ [bug] set "version of encoding software" to 2.0
++ [bug?] keep extended local headers when copying?
+- [feature] Windows support: (partially fixed?)
   . better mkstemp replacement function (no getpid; other problems?)
   . snprintf replacement
   . strcasecmp replacement
-  . ssize_t define
   . mode_t define
   . dll_export/dll_import support (to clarify)
 - [cleanup] remove now useless check of fseek 
@@ -27,23 +31,24 @@
   . read/set ASCII file flag
 - [test] rename deleted (fails)
 - [test] rename file to dir/ and vice versa (fails)
+------------------------------------------------ API issues
+- character encoding in file names and comments (ZIP_AFL_UTF8, see mail)
+- parameters for compression/crypt implementations (extra function)
+  ZIP_CM_DEFLATE/ZIP_CM_BZIP2: compression level
+  			       memlevel?
+* compression/crypt implementations: how to set error code on failure
++ compression/crypt error messages a la ZIP_ER_ZLIB (no detailed info passing)
+* I/O methods
 ------------------------------------------------ API ideas
 struct zip *zip_open_encrypted(const char *path, int flags,
                                const char *password, int *errorp);
-void zip_set_default_password(struct zip *archive, const char *password);
-(NULL for unsetting)
 
-struct zip_file *zip_fopen_encrypted(struct zip *archive,
-                                     const char *fname, int flags,
-                                     const char *password);
-struct zip_file *zip_fopen_index_encrypted(struct zip *archive,
-                                           int index, int flags,
-                                           const char *password);
-
-int zip_set_encryption(struct zip *archive, int idx, int method,
-                       const char *password);
-void zip_set_archive_encryption(struct zip *archive, int encryption_method,
-                                const char *password);
+int zip_set_compression(struct zip *archive, zip_uint64_t idx,
+    			zip_uint16_t method);
+int zip_set_encryption(struct zip *archive, zip_uint64_t idx,
+    		       zip_uint16_t method, const char *password);
+void zip_set_archive_encryption(struct zip *archive,
+     				zip_uint16_t method, const char *password);
 
 struct zip_source *zip_source_writable(struct zip *archive);
 zip_source_write(struct zip_source *, const void *data, size_t len);
diff --git a/cmake-zipconf.h.in b/cmake-zipconf.h.in
new file mode 100644
index 0000000..fd8f701
--- /dev/null
+++ b/cmake-zipconf.h.in
@@ -0,0 +1,97 @@
+#ifndef _HAD_ZIPCONF_H
+#define _HAD_ZIPCONF_H
+
+/*
+   zipconf.h -- platform specific include file
+
+   This file was generated automatically by CMake
+   based on ../cmake-zipconf.h.
+ */
+
+#cmakedefine HAVE_INTTYPES_H_LIBZIP
+#cmakedefine HAVE_SYS_TYPES_H_LIBZIP
+#cmakedefine HAVE_INT8_T_LIBZIP
+#cmakedefine HAVE_UINT8_T_LIBZIP
+#cmakedefine HAVE_INT16_T_LIBZIP
+#cmakedefine HAVE_UINT16_T_LIBZIP
+#cmakedefine HAVE_INT32_T_LIBZIP
+#cmakedefine HAVE_UINT32_T_LIBZIP
+#cmakedefine HAVE_INT64_T_LIBZIP
+#cmakedefine HAVE_UINT64_T_LIBZIP
+#cmakedefine SHORT_LIBZIP ${SHORT_LIBZIP}
+#cmakedefine INT_LIBZIP ${INT_LIBZIP}
+#cmakedefine LONG_LIBZIP ${LONG_LIBZIP}
+#cmakedefine LONGLONG_LIBZIP ${LONGLONG_LIBZIP}
+
+#if defined(HAVE_INTTYPES_H_LIBZIP)
+#include <inttypes.h>
+#elif defined(HAVE_SYS_TYPES_H_LIBZIP)
+#include <sys/types.h>
+#endif
+
+#if defined(HAVE_INT8_T_LIBZIP)
+typedef int8_t zip_int8_t;
+#else
+typedef signed char zip_int8_t;
+#endif
+#if defined(HAVE_UINT8_T_LIBZIP)
+typedef uint8_t zip_uint8_t;
+#else
+typedef unsigned char zip_uint8_t;
+#endif
+#if defined(HAVE_INT16_T_LIBZIP)
+typedef int16_t zip_int16_t;
+#elif defined(SHORT_LIBZIP) && SHORT_LIBZIP == 2
+typedef signed short zip_int16_t;
+#endif
+#if defined(HAVE_UINT16_T_LIBZIP)
+typedef uint16_t zip_uint16_t;
+#elif defined(SHORT_LIBZIP) && SHORT_LIBZIP == 2
+typedef unsigned short zip_uint16_t;
+#endif
+#if defined(HAVE_INT32_T_LIBZIP)
+typedef int32_t zip_int32_t;
+#elif defined(INT_LIBZIP) && INT_LIBZIP == 4
+typedef signed int zip_int32_t;
+#elif defined(LONG_LIBZIP) && LONG_LIBZIP == 4
+typedef signed long zip_int32_t;
+#endif
+#if defined(HAVE_UINT32_T_LIBZIP)
+typedef uint32_t zip_uint32_t;
+#elif defined(INT_LIBZIP) && INT_LIBZIP == 4
+typedef unsigned int zip_uint32_t;
+#elif defined(LONG_LIBZIP) && LONG_LIBZIP == 4
+typedef unsigned long zip_uint32_t;
+#endif
+#if defined(HAVE_INT64_T_LIBZIP)
+typedef int64_t zip_int64_t;
+#elif defined(LONG_LIBZIP) && LONG_LIBZIP == 8
+typedef signed long zip_int64_t;
+#elif defined(LONGLONG_LIBZIP) && LONGLONG_LIBZIP == 8
+typedef signed long long zip_int64_t;
+#endif
+#if defined(HAVE_UINT64_T_LIBZIP)
+typedef uint64_t zip_uint64_t;
+#elif defined(LONG_LIBZIP) && LONGLONG_LIBZIP == 8
+typedef unsigned long zip_uint64_t;
+#elif defined(LONGLONG_LIBZIP) && LONGLONG_LIBZIP == 8
+typedef unsigned long long zip_uint64_t;
+#endif
+
+#define ZIP_INT8_MIN	-0x80
+#define ZIP_INT8_MAX	 0x7f
+#define ZIP_UINT8_MAX	 0xff
+
+#define ZIP_INT16_MIN	-0x8000
+#define ZIP_INT16_MAX	 0x7fff
+#define ZIP_UINT16_MAX	 0xffff
+
+#define ZIP_INT32_MIN	-0x80000000L
+#define ZIP_INT32_MAX	 0x7fffffffL
+#define ZIP_UINT32_MAX	 0xffffffffLU
+
+#define ZIP_INT64_MIN	-0x8000000000000000LL
+#define ZIP_INT64_MAX	 0x7fffffffffffffffLL
+#define ZIP_UINT64_MAX	 0xffffffffffffffffLLU
+
+#endif /* zipconf.h */
diff --git a/configure.ac b/configure.ac
index 5a8bbf5..3129fe3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,6 @@
 AC_PREREQ(2.57)
-AC_INIT([libzip],[0.9.1],[libzip@nih.at])
+# also update CMakeLists.txt when changing version
+AC_INIT([libzip],[0.9.1a],[libzip@nih.at])
 AC_CONFIG_SRCDIR([lib/zip_add.c])
 AC_CONFIG_HEADERS([config.h])
 AM_INIT_AUTOMAKE
@@ -54,6 +55,20 @@
 
 AC_CHECK_HEADERS([unistd.h])
 
+AC_CHECK_TYPES([int8_t])
+AC_CHECK_TYPES([int16_t])
+AC_CHECK_TYPES([int32_t])
+AC_CHECK_TYPES([int64_t])
+AC_CHECK_TYPES([uint8_t])
+AC_CHECK_TYPES([uint16_t])
+AC_CHECK_TYPES([uint32_t])
+AC_CHECK_TYPES([uint64_t])
+
+AC_CHECK_SIZEOF([short])
+AC_CHECK_SIZEOF([int])
+AC_CHECK_SIZEOF([long])
+AC_CHECK_SIZEOF([long long])
+
 AC_STRUCT_TIMEZONE
 
 case $host_os
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 4c97a62..21695b8 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -1,5 +1,3 @@
-# $NiH$
-
 INCLUDE(CheckFunctionExists)
 
 INSTALL(FILES zip.h DESTINATION include)
@@ -62,7 +60,7 @@
   zip_dirent.c
   zip_entry_free.c
   zip_entry_new.c
-  ${CMAKE_CURRENT_BINARY_DIR}/zip_err_str.c
+  zip_err_str.c
   zip_error.c
   zip_error_clear.c
   zip_error_get.c
@@ -70,18 +68,25 @@
   zip_error_strerror.c
   zip_error_to_str.c
   zip_fclose.c
+  zip_fdopen.c
   zip_file_error_clear.c
   zip_file_error_get.c
   zip_file_get_offset.c
   zip_file_strerror.c
+  zip_filerange_crc.c
   zip_fopen.c
+  zip_fopen_encrypted.c
   zip_fopen_index.c
+  zip_fopen_index_encrypted.c
   zip_fread.c
   zip_free.c
   zip_get_archive_comment.c
+  zip_get_archive_flag.c
+  zip_get_compression_implementation.c
+  zip_get_encryption_implementation.c
   zip_get_file_comment.c
-  zip_get_num_files.c
   zip_get_name.c
+  zip_get_num_files.c
   zip_memdup.c
   zip_name_locate.c
   zip_new.c
@@ -89,14 +94,26 @@
   zip_rename.c
   zip_replace.c
   zip_set_archive_comment.c
+  zip_set_archive_flag.c
+  zip_set_default_password.c
   zip_set_file_comment.c
+  zip_set_name.c
   zip_source_buffer.c
+  zip_source_close.c
+  zip_source_crc.c
+  zip_source_deflate.c
+  zip_source_error.c
   zip_source_file.c
   zip_source_filep.c
   zip_source_free.c
   zip_source_function.c
+  zip_source_layered.c
+  zip_source_open.c
+  zip_source_pkware.c
+  zip_source_pop.c
+  zip_source_read.c
+  zip_source_stat.c
   zip_source_zip.c
-  zip_set_name.c
   zip_stat.c
   zip_stat_index.c
   zip_stat_init.c
@@ -111,19 +128,22 @@
   ${CMAKE_CURRENT_BINARY_DIR}/..)
 
 # XXX: distribute instead?
-ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zip_err_str.c
-  COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/make_zip_err_str.sh
-    ${CMAKE_CURRENT_SOURCE_DIR}/zip.h
-    ${CMAKE_CURRENT_BINARY_DIR}/zip_err_str.c
-  DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/zip.h
-    ${CMAKE_CURRENT_SOURCE_DIR}/make_zip_err_str.sh
-)
+#ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zip_err_str.c
+#  COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/make_zip_err_str.sh
+#    ${CMAKE_CURRENT_SOURCE_DIR}/zip.h
+#    ${CMAKE_CURRENT_BINARY_DIR}/zip_err_str.c
+#  DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/zip.h
+#    ${CMAKE_CURRENT_SOURCE_DIR}/make_zip_err_str.sh
+#)
 CHECK_FUNCTION_EXISTS(mkstemp HAVE_MKSTEMP)
 IF(NOT HAVE_MKSTEMP)
   SET(LIBZIP_EXTRA_FILES mkstemp.c)
 ENDIF(NOT HAVE_MKSTEMP)
 
 ADD_LIBRARY(zip SHARED ${LIBZIP_SOURCES} ${LIBZIP_EXTRA_FILES})
-SET_TARGET_PROPERTIES(zip PROPERTIES VERSION 1.0 SOVERSION 1 )
+SET_TARGET_PROPERTIES(zip PROPERTIES VERSION 2.0 SOVERSION 2 )
 TARGET_LINK_LIBRARIES(zip z)
+INSTALL(TARGETS zip
+	ARCHIVE DESTINATION lib
+	LIBRARY DESTINATION lib)
 #CREATE_LIBTOOL_FILE(zip lib)
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 5a6d095..f4f6d65 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -1,8 +1,12 @@
+libincludedir = ${libdir}/@PACKAGE@/include
+
 lib_LTLIBRARIES = libzip.la
 noinst_HEADERS = zipint.h
 include_HEADERS = zip.h
+libinclude_HEADERS = zipconf.h
 
-libzip_la_LDFLAGS=-no-undefined -version-info 1:0
+# also update CMakeLists.txt when changing version
+libzip_la_LDFLAGS=-no-undefined -version-info 2:0
 libzip_la_LIBADD=@LTLIBOBJS@
 
 libzip_la_SOURCES=\
@@ -21,17 +25,22 @@
 	zip_error_strerror.c \
 	zip_error_to_str.c \
 	zip_fclose.c \
+	zip_fdopen.c \
 	zip_file_error_clear.c \
 	zip_file_error_get.c \
 	zip_file_get_offset.c \
 	zip_file_strerror.c \
 	zip_filerange_crc.c \
 	zip_fopen.c \
+	zip_fopen_encrypted.c \
 	zip_fopen_index.c \
+	zip_fopen_index_encrypted.c \
 	zip_fread.c \
 	zip_free.c \
 	zip_get_archive_comment.c \
 	zip_get_archive_flag.c \
+	zip_get_compression_implementation.c \
+	zip_get_encryption_implementation.c \
 	zip_get_file_comment.c \
 	zip_get_num_files.c \
 	zip_get_name.c \
@@ -43,12 +52,23 @@
 	zip_replace.c \
 	zip_set_archive_comment.c \
 	zip_set_archive_flag.c \
+	zip_set_default_password.c \
 	zip_set_file_comment.c \
 	zip_source_buffer.c \
+	zip_source_close.c \
+	zip_source_crc.c \
+	zip_source_deflate.c \
+	zip_source_error.c \
 	zip_source_file.c \
 	zip_source_filep.c \
 	zip_source_free.c \
 	zip_source_function.c \
+	zip_source_layered.c \
+	zip_source_open.c \
+	zip_source_pkware.c \
+	zip_source_pop.c \
+	zip_source_read.c \
+	zip_source_stat.c \
 	zip_source_zip.c \
 	zip_set_name.c \
 	zip_stat.c \
@@ -60,10 +80,13 @@
 	zip_unchange_archive.c \
 	zip_unchange_data.c
 
-BUILT_SOURCES=zip_err_str.c
+BUILT_SOURCES=zip_err_str.c zipconf.h
 
 EXTRA_DIST=	CMakeLists.txt \
 		make_zip_err_str.sh
 
 zip_err_str.c: zip.h make_zip_err_str.sh
 	sh $(srcdir)/make_zip_err_str.sh $(srcdir)/zip.h zip_err_str.c
+
+zipconf.h: ${top_builddir}/config.h make_zipconf.sh
+	sh ${srcdir}/make_zipconf.sh ${top_builddir}/config.h zipconf.h
diff --git a/lib/make_zip_err_str.sh b/lib/make_zip_err_str.sh
index e51b172..51ea9b9 100644
--- a/lib/make_zip_err_str.sh
+++ b/lib/make_zip_err_str.sh
@@ -45,9 +45,6 @@
     exit 1
 fi
 
-#rcsid=`echo '$NiH: make_zip_err_str.sh,v 1.7 2004/04/25 16:20:16 dillo Exp $' | tr -d '$'`
-#inrcsid=`sed -n 's/^  \$\([^$]*[^ ]\) *\$$/\1/p' "$1"`
-
 cat <<EOF >> "$2.$$" || exit 1
 /*
    This file was generated automatically by $0
diff --git a/lib/make_zipconf.sh b/lib/make_zipconf.sh
new file mode 100644
index 0000000..48a2951
--- /dev/null
+++ b/lib/make_zipconf.sh
@@ -0,0 +1,163 @@
+#!/bin/sh
+
+#  make_zipconf.sh: create platform specific include file zipconf.h
+#  Copyright (C) 1999-2009 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.
+
+
+set -e
+
+define_type()
+{
+    short=$1
+    long=$2
+    bytes=$3
+    infile="$4"
+    outfile="$5"
+
+    bits=`expr $bytes '*' 8`
+    type="${short}int${bits}"
+    TYPE=`echo $type | tr a-z A-Z`
+    if grep -q "define HAVE_${TYPE}_T" "$infile"
+    then
+	echo "typedef ${type}_t zip_${type}_t;" >> "$outfile"
+	LTYPE="$TYPE"
+    else
+	SHORT=`echo $short | tr a-z A-Z`
+	if [ -z "$SHORT" ]
+	then
+	    SHORT='S'
+	fi
+	if [ "$bytes" -eq 1 ]
+	then
+	    if [ -z "$long" ]
+	    then
+		long='signed'
+	    fi
+	    echo "typedef $long char ${type}_t;" >> $outfile
+	    LTYPE="${SHORT}CHAR"
+	else
+	    ctype=`sed -n "s/.define SIZEOF_\([A-Z_]*\) $bytes/\1/p" "$infile" \
+		| head -1 | tr A-Z_ 'a-z '`
+	    if [ -z "$ctype" ]
+	    then
+		echo "$0: no $bits bit type found" >&2
+		exit 1
+	    fi
+	    echo "typedef $long $ctype ${type}_t;" >> "$outfile"
+	    case "$ctype" in
+		short) LTYPE=${SHORT}SHRT;;
+		int) LTYPE=${SHORT}INT;;
+                long) LTYPE=${SHORT}LONG;;
+		"long long") LTYPE=${SHORT}LLONG;;
+            esac
+	fi
+    fi
+
+    if [ -z "$long" ]
+    then
+	echo "#define ZIP_${TYPE}_MIN ${LTYPE}_MIN" >> "$outfile"
+    fi
+    echo "#define ZIP_${TYPE}_MAX ${LTYPE}_MAX" >> "$outfile"
+    echo >> "$outfile"
+}
+
+
+if [ "$#" -ne 2 ]
+then
+    echo "Usage: $0 config_h_file out_file" >&2
+    echo "       e.g. $0 ../config.h zip_err_str.c" >&2
+    exit 1
+fi
+
+if [ "$1" = "$2" ]
+then
+    echo "$0: error: output file = input file" >&2
+    exit 1
+fi
+
+cat <<EOF > "$2.$$"
+#ifndef _HAD_ZIPCONF_H
+#define _HAD_ZIPCONF_H
+
+/*
+   zipconf.h -- platform specific include file
+
+   This file was generated automatically by $0
+   based on $1.
+ */
+
+EOF
+
+version=`sed -n 's/^#define VERSION "\(.*\)"/\1/p' "$1"`
+
+version_major=`expr "$version" : '^\([0-9]*\)' || true`
+version_minor=`expr "$version" : '^[0-9]*\.\([0-9]*\)' || true`
+version_micro=`expr "$version" : '^[0-9]*\.[0-9]\.\([0-9]*\)' || true`
+
+if [ -z "$version_major" ]
+then
+    version_major=0
+fi
+if [ -z "$version_minor" ]
+then
+    version_minor=0
+fi
+if [ -z "$version_micro" ]
+then
+    version_micro=0
+fi
+
+cat <<EOF >> "$2.$$"
+#define LIBZIP_VERSION "$version"
+#define LIBZIP_VERSION_MAJOR $version_major
+#define LIBZIP_VERSION_MINOR $version_minor
+#define LIBZIP_VERSION_MICRO $version_micro
+
+EOF
+
+if grep -q 'define HAVE_INTTYPES_H' "$1"
+then
+    echo '#include <inttypes.h>' >> "$2.$$"
+else
+    echo '#include <limits.h>' >> "$2.$$"
+fi
+echo >> "$2.$$"
+
+for size in 1 2 4 8
+do
+    define_type '' '' $size "$1" "$2.$$"
+    define_type u unsigned $size "$1" "$2.$$"
+done
+
+echo >> "$2.$$"
+echo '#endif /* zipconf.h */' >> "$2.$$"
+
+mv "$2.$$" "$2"
diff --git a/lib/mkstemp.c b/lib/mkstemp.c
index 738a065..e935f53 100644
--- a/lib/mkstemp.c
+++ b/lib/mkstemp.c
@@ -1,5 +1,3 @@
-/* $NiH: mkstemp.c,v 1.3 2006/04/23 14:51:45 wiz Exp $ */
-
 /* Adapted from NetBSB libc by Dieter Baron */
 
 /*	NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp 	*/
diff --git a/lib/zip.h b/lib/zip.h
index 48431a3..fe67d23 100644
--- a/lib/zip.h
+++ b/lib/zip.h
@@ -3,7 +3,7 @@
 
 /*
   zip.h -- exported declarations.
-  Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -48,6 +48,8 @@
 extern "C" {
 #endif
 
+#include <zipconf.h>
+
 #include <sys/types.h>
 #include <stdio.h>
 #include <time.h>
@@ -66,10 +68,19 @@
 #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 */
+#define ZIP_FL_ENCRYPTED       32 /* read encrypted data
+				     (implies ZIP_FL_COMPRESSED) */
 
 /* archive global flags flags */
 
 #define ZIP_AFL_TORRENT		1 /* torrent zipped */
+#define ZIP_AFL_RDONLY		2 /* read only -- cannot be cleared */
+
+
+/* flags for compression and encryption sources */
+
+#define ZIP_CODEC_ENCODE	1 /* compress/encrypt */
+
 
 /* libzip error codes */
 
@@ -97,7 +108,10 @@
 #define ZIP_ER_INCONS        21  /* N Zip archive inconsistent */
 #define ZIP_ER_REMOVE        22  /* S Can't remove file */
 #define ZIP_ER_DELETED       23  /* N Entry has been deleted */
-
+#define ZIP_ER_ENCRNOTSUPP   24  /* N Encryption method not supported */
+#define ZIP_ER_RDONLY        25  /* N Read-only archive */ 
+#define ZIP_ER_NOPASSWD      26  /* N No password provided */
+#define ZIP_ER_WRONGPASSWD   27  /* N Wrong password provided */
 
 /* type of system error value */
 
@@ -154,72 +168,131 @@
     ZIP_SOURCE_CLOSE,	/* reading is done */
     ZIP_SOURCE_STAT,	/* get meta information */
     ZIP_SOURCE_ERROR,	/* get error information */
-    ZIP_SOURCE_FREE	/* cleanup and free resources */
+    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);
+#define ZIP_SOURCE_ERR_LOWER	-2
+
+#define ZIP_STAT_NAME			0x0001
+#define ZIP_STAT_INDEX			0x0002
+#define ZIP_STAT_SIZE			0x0004
+#define ZIP_STAT_COMP_SIZE		0x0008
+#define ZIP_STAT_MTIME			0x0010
+#define ZIP_STAT_CRC			0x0020
+#define ZIP_STAT_COMP_METHOD		0x0040
+#define ZIP_STAT_ENCRYPTION_METHOD	0x0080
+#define ZIP_STAT_FLAGS			0x0100
 
 struct zip_stat {
+    zip_uint64_t valid;			/* which fields have valid values */
     const char *name;			/* name of the file */
-    int index;				/* index within archive */
-    unsigned int crc;			/* crc of file data */
+    zip_uint64_t index;			/* index within archive */
+    zip_uint64_t size;			/* size of file (uncompressed) */
+    zip_uint64_t comp_size;		/* size of file (compressed) */
     time_t mtime;			/* modification time */
-    off_t size;				/* size of file (uncompressed) */
-    off_t comp_size;			/* size of file (compressed) */
-    unsigned short comp_method;		/* compression method used */
-    unsigned short encryption_method;	/* encryption method used */
+    zip_uint32_t crc;			/* crc of file data */
+    zip_uint16_t comp_method;		/* compression method used */
+    zip_uint16_t encryption_method;	/* encryption method used */
+    zip_uint32_t flags;			/* reserved for future use */
 };
 
 struct zip;
 struct zip_file;
 struct zip_source;
 
+typedef zip_int64_t (*zip_source_callback)(void *, void *, zip_uint64_t,
+					   enum zip_source_cmd);
+typedef zip_int64_t (*zip_source_layered_callback)(struct zip_source *, void *,
+						   void *, zip_uint64_t,
+						   enum zip_source_cmd);
+typedef struct zip_source *(*zip_compression_implementation)(struct zip *,
+						     struct zip_source *,
+						     zip_uint16_t, int);
+typedef struct zip_source *(*zip_encryption_implementation)(struct zip *,
+						    struct zip_source *,
+						    zip_uint16_t, int,
+						    const char *);
+
 
 
-ZIP_EXTERN int zip_add(struct zip *, const char *, struct zip_source *);
-ZIP_EXTERN int zip_add_dir(struct zip *, const char *);
+ZIP_EXTERN zip_int64_t zip_add(struct zip *, const char *, struct zip_source *);
+ZIP_EXTERN zip_int64_t zip_add_dir(struct zip *, const char *);
 ZIP_EXTERN int zip_close(struct zip *);
-ZIP_EXTERN int zip_delete(struct zip *, int);
+ZIP_EXTERN int zip_delete(struct zip *, zip_uint64_t);
 ZIP_EXTERN void zip_error_clear(struct zip *);
 ZIP_EXTERN void zip_error_get(struct zip *, int *, int *);
 ZIP_EXTERN int zip_error_get_sys_type(int);
-ZIP_EXTERN int zip_error_to_str(char *, size_t, int, int);
+ZIP_EXTERN int zip_error_to_str(char *, zip_uint64_t, int, int);
 ZIP_EXTERN int zip_fclose(struct zip_file *);
+ZIP_EXTERN struct zip *zip_fdopen(int, int, int *);
 ZIP_EXTERN void zip_file_error_clear(struct zip_file *);
 ZIP_EXTERN void zip_file_error_get(struct zip_file *, int *, int *);
 ZIP_EXTERN const char *zip_file_strerror(struct zip_file *);
 ZIP_EXTERN struct zip_file *zip_fopen(struct zip *, const char *, int);
-ZIP_EXTERN struct zip_file *zip_fopen_index(struct zip *, int, int);
-ZIP_EXTERN ssize_t zip_fread(struct zip_file *, void *, size_t);
+ZIP_EXTERN struct zip_file *zip_fopen_encrypted(struct zip *, const char *,
+						int, const char *);
+ZIP_EXTERN struct zip_file *zip_fopen_index(struct zip *, zip_uint64_t, int);
+ZIP_EXTERN struct zip_file *zip_fopen_index_encrypted(struct zip *,
+						      zip_uint64_t, int,
+						      const char *);
+ZIP_EXTERN zip_int64_t zip_fread(struct zip_file *, void *, zip_uint64_t);
 ZIP_EXTERN const char *zip_get_archive_comment(struct zip *, int *, int);
 ZIP_EXTERN int zip_get_archive_flag(struct zip *, int, int);
-ZIP_EXTERN const char *zip_get_file_comment(struct zip *, int, int *, int);
-ZIP_EXTERN const char *zip_get_name(struct zip *, int, int);
+ZIP_EXTERN zip_compression_implementation zip_get_compression_implementation(
+    zip_uint16_t);
+ZIP_EXTERN zip_encryption_implementation zip_get_encryption_implementation(
+    zip_uint16_t);
+ZIP_EXTERN const char *zip_get_file_comment(struct zip *, zip_uint64_t,
+					    int *, int);
+ZIP_EXTERN const char *zip_get_name(struct zip *, zip_uint64_t, int);
 ZIP_EXTERN int zip_get_num_files(struct zip *);
 ZIP_EXTERN int zip_name_locate(struct zip *, const char *, int);
 ZIP_EXTERN struct zip *zip_open(const char *, int, int *);
-ZIP_EXTERN int zip_rename(struct zip *, int, const char *);
-ZIP_EXTERN int zip_replace(struct zip *, int, struct zip_source *);
+ZIP_EXTERN int zip_rename(struct zip *, zip_uint64_t, const char *);
+ZIP_EXTERN int zip_replace(struct zip *, zip_uint64_t, struct zip_source *);
 ZIP_EXTERN int zip_set_archive_comment(struct zip *, const char *, int);
 ZIP_EXTERN int zip_set_archive_flag(struct zip *, int, int);
-ZIP_EXTERN int zip_set_file_comment(struct zip *, int, const char *, int);
+ZIP_EXTERN int zip_set_default_password(struct zip *, const char *);
+ZIP_EXTERN int zip_set_file_comment(struct zip *, zip_uint64_t,
+				    const char *, int);
 ZIP_EXTERN struct zip_source *zip_source_buffer(struct zip *, const void *,
-						off_t, int);
+						zip_uint64_t, int);
+ZIP_EXTERN void zip_source_close(struct zip_source *);
+ZIP_EXTERN struct zip_source *zip_source_crc(struct zip *, struct zip_source *,
+					     int);
+ZIP_EXTERN struct zip_source *zip_source_deflate(struct zip *,
+						 struct zip_source *,
+						 zip_uint16_t, int);
+ZIP_EXTERN void zip_source_error(struct zip_source *, int *, int *);
 ZIP_EXTERN struct zip_source *zip_source_file(struct zip *, const char *,
-					      off_t, off_t);
+					      zip_uint64_t, zip_int64_t);
 ZIP_EXTERN struct zip_source *zip_source_filep(struct zip *, FILE *,
-					       off_t, off_t);
+					       zip_uint64_t, zip_int64_t);
 ZIP_EXTERN void zip_source_free(struct zip_source *);
 ZIP_EXTERN struct zip_source *zip_source_function(struct zip *,
 						  zip_source_callback, void *);
+ZIP_EXTERN struct zip_source *zip_source_layered(struct zip *,
+						 struct zip_source *,
+						 zip_source_layered_callback,
+						 void *);
+ZIP_EXTERN int zip_source_open(struct zip_source *);
+ZIP_EXTERN struct zip_source *zip_source_pkware(struct zip *,
+						struct zip_source *,
+						zip_uint16_t, int,
+						const char *);
+ZIP_EXTERN struct zip_source *zip_source_pop(struct zip_source *);
+ZIP_EXTERN zip_int64_t zip_source_read(struct zip_source *, void *,
+				       zip_uint64_t);
+ZIP_EXTERN int zip_source_stat(struct zip_source *, struct zip_stat *);
 ZIP_EXTERN struct zip_source *zip_source_zip(struct zip *, struct zip *,
-					     int, int, off_t, off_t);
+					     zip_uint64_t, int,
+					     zip_uint64_t, zip_int64_t);
 ZIP_EXTERN int zip_stat(struct zip *, const char *, int, struct zip_stat *);
-ZIP_EXTERN int zip_stat_index(struct zip *, int, int, struct zip_stat *);
+ZIP_EXTERN int zip_stat_index(struct zip *, zip_uint64_t, int,
+			      struct zip_stat *);
 ZIP_EXTERN void zip_stat_init(struct zip_stat *);
 ZIP_EXTERN const char *zip_strerror(struct zip *);
-ZIP_EXTERN int zip_unchange(struct zip *, int);
+ZIP_EXTERN int zip_unchange(struct zip *, zip_uint64_t);
 ZIP_EXTERN int zip_unchange_all(struct zip *);
 ZIP_EXTERN int zip_unchange_archive(struct zip *);
 
diff --git a/lib/zip_add.c b/lib/zip_add.c
index f6bdb2a..6a310a8 100644
--- a/lib/zip_add.c
+++ b/lib/zip_add.c
@@ -37,7 +37,14 @@
 
 
 
-ZIP_EXTERN int
+/*
+  NOTE: Return type is signed so we can return -1 on error.
+        The index can not be larger than ZIP_INT64_MAX since the size
+        of the central directory cannot be larger than
+        ZIP_UINT64_MAX, and each entry is larger than 2 bytes.
+*/
+
+ZIP_EXTERN zip_int64_t
 zip_add(struct zip *za, const char *name, struct zip_source *source)
 {
     if (name == NULL || source == NULL) {
@@ -45,5 +52,5 @@
 	return -1;
     }
 	
-    return _zip_replace(za, -1, name, source);
+    return _zip_replace(za, ZIP_UINT64_MAX, name, source);
 }
diff --git a/lib/zip_add_dir.c b/lib/zip_add_dir.c
index 493e28d..28a8ad1 100644
--- a/lib/zip_add_dir.c
+++ b/lib/zip_add_dir.c
@@ -1,6 +1,6 @@
 /*
   zip_add_dir.c -- add directory
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -40,13 +40,21 @@
 
 
 
-ZIP_EXTERN int
+/* NOTE: Signed due to -1 on error.  See zip_add.c for more details. */
+
+ZIP_EXTERN zip_int64_t
 zip_add_dir(struct zip *za, const char *name)
 {
-    int len, ret;
+    int len;
+    zip_int64_t ret;
     char *s;
     struct zip_source *source;
 
+    if (ZIP_IS_RDONLY(za)) {
+	_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+	return -1;
+    }
+
     if (name == NULL) {
 	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
 	return -1;
diff --git a/lib/zip_close.c b/lib/zip_close.c
index 49af3bb..c993000 100644
--- a/lib/zip_close.c
+++ b/lib/zip_close.c
@@ -1,6 +1,6 @@
 /*
   zip_close.c -- close zip archive and update changes
-  Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -44,15 +44,10 @@
 
 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(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 copy_source(struct zip *, struct zip_source *, FILE *);
 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 *);
 
@@ -135,6 +130,7 @@
 
     if ((temp=_zip_create_temp_output(za, &out)) == NULL) {
 	_zip_cdir_free(cd);
+	free(filelist);
 	return -1;
     }
 
@@ -241,8 +237,13 @@
 
 	    if (add_data(za, zs ? zs : za->entry[i].source, &de, out) < 0) {
 		error = 1;
+		if (zs)
+		    zip_source_free(zs);
 		break;
 	    }
+	    if (zs)
+		zip_source_free(zs);
+	    
 	    cd->entry[j].last_mod = de.last_mod;
 	    cd->entry[j].comp_method = de.comp_method;
 	    cd->entry[j].comp_size = de.comp_size;
@@ -317,23 +318,17 @@
 
 
 static int
-add_data(struct zip *za, struct zip_source *zs, struct zip_dirent *de, FILE *ft)
+add_data(struct zip *za, struct zip_source *src, struct zip_dirent *de,
+	 FILE *ft)
 {
-    off_t offstart, offend;
-    zip_source_callback cb;
-    void *ud;
+    off_t offstart, offdata, offend;
     struct zip_stat st;
+    struct zip_source *s2;
+    zip_compression_implementation comp_impl;
+    int ret;
     
-    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);
-	return -1;
-    }
-
-    if (cb(ud, NULL, 0, ZIP_SOURCE_OPEN) < 0) {
-	ch_set_error(&za->error, cb, ud);
+    if (zip_source_stat(src, &st) < 0) {
+	_zip_error_set_from_source(&za->error, src);
 	return -1;
     }
 
@@ -342,19 +337,49 @@
     if (_zip_dirent_write(de, ft, 1, &za->error) < 0)
 	return -1;
 
-    if (st.comp_method != ZIP_CM_STORE) {
-	if (add_data_comp(cb, ud, &st, ft, &za->error) < 0)
-	    return -1;
-    }
-    else {
-	if (add_data_uncomp(za, cb, ud, &st, ft) < 0)
-	    return -1;
-    }
-
-    if (cb(ud, NULL, 0, ZIP_SOURCE_CLOSE) < 0) {
-	ch_set_error(&za->error, cb, ud);
+    if ((s2=zip_source_crc(za, src, 0)) == NULL) {
+	zip_source_pop(s2);
 	return -1;
     }
+    
+    /* XXX: deflate 0-byte files for torrentzip? */
+    if (((st.valid & ZIP_STAT_COMP_METHOD) == 0
+	 || st.comp_method == ZIP_CM_STORE)
+	&& ((st.valid & ZIP_STAT_SIZE) == 0 || st.size != 0)) {
+	comp_impl = NULL;
+	if ((comp_impl=zip_get_compression_implementation(ZIP_CM_DEFLATE))
+	    == NULL) {
+	    _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
+	    zip_source_pop(s2);
+	    return -1;
+	}
+	if ((s2=comp_impl(za, s2, ZIP_CM_DEFLATE, ZIP_CODEC_ENCODE))
+	    == NULL) {
+	    /* XXX: set error? */
+	    zip_source_pop(s2);
+	    return -1;
+	}
+    }
+    else
+	s2 = src;
+
+    offdata = ftello(ft);
+	
+    ret = copy_source(za, s2, ft);
+	
+    if (zip_source_stat(s2, &st) < 0)
+	ret = -1;
+    
+    while (s2 != src) {
+	if ((s2=zip_source_pop(s2)) == NULL) {
+	    /* XXX: set erorr */
+	    ret = -1;
+	    break;
+	}
+    }
+
+    if (ret < 0)
+	return -1;
 
     offend = ftello(ft);
 
@@ -363,12 +388,11 @@
 	return -1;
     }
 
-    
     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;
+    de->comp_size = offend - offdata;
 
     if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
 	_zip_dirent_torrent_normalize(de);
@@ -387,132 +411,6 @@
 
 
 static int
-add_data_comp(zip_source_callback cb, void *ud, struct zip_stat *st,FILE *ft,
-	      struct zip_error *error)
-{
-    char buf[BUFSIZE];
-    ssize_t n;
-
-    st->comp_size = 0;
-    while ((n=cb(ud, buf, sizeof(buf), ZIP_SOURCE_READ)) > 0) {
-	if (fwrite(buf, 1, n, ft) != (size_t)n) {
-	    _zip_error_set(error, ZIP_ER_WRITE, errno);
-	    return -1;
-	}
-	
-	st->comp_size += n;
-    }
-    if (n < 0) {
-	ch_set_error(error, cb, ud);
-	return -1;
-    }	
-
-    return 0;
-}
-
-
-
-static int
-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;
-    st->crc = crc32(0, NULL, 0);
-
-    zstr.zalloc = Z_NULL;
-    zstr.zfree = Z_NULL;
-    zstr.opaque = NULL;
-    zstr.avail_in = 0;
-    zstr.avail_out = 0;
-
-    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;
-    zstr.avail_out = sizeof(b2);
-    zstr.avail_in = 0;
-
-    flush = 0;
-    end = 0;
-    while (!end) {
-	if (zstr.avail_in == 0 && !flush) {
-	    if ((n=cb(ud, b1, sizeof(b1), ZIP_SOURCE_READ)) < 0) {
-		ch_set_error(&za->error, cb, ud);
-		deflateEnd(&zstr);
-		return -1;
-	    }
-	    if (n > 0) {
-		zstr.avail_in = n;
-		zstr.next_in = (Bytef *)b1;
-		st->size += n;
-		st->crc = crc32(st->crc, (Bytef *)b1, n);
-	    }
-	    else
-		flush = Z_FINISH;
-	}
-
-	ret = deflate(&zstr, flush);
-	if (ret != Z_OK && ret != Z_STREAM_END) {
-	    _zip_error_set(&za->error, ZIP_ER_ZLIB, ret);
-	    return -1;
-	}
-	
-	if (zstr.avail_out != sizeof(b2)) {
-	    n2 = sizeof(b2) - zstr.avail_out;
-	    
-	    if (fwrite(b2, 1, n2, ft) != n2) {
-		_zip_error_set(&za->error, ZIP_ER_WRITE, errno);
-		return -1;
-	    }
-	
-	    zstr.next_out = (Bytef *)b2;
-	    zstr.avail_out = sizeof(b2);
-	    st->comp_size += n2;
-	}
-
-	if (ret == Z_STREAM_END) {
-	    deflateEnd(&zstr);
-	    end = 1;
-	}
-    }
-
-    return 0;
-}
-
-
-
-static void
-ch_set_error(struct zip_error *error, zip_source_callback cb, void *ud)
-{
-    int e[2];
-
-    if ((cb(ud, e, sizeof(e), ZIP_SOURCE_ERROR)) < (ssize_t)sizeof(e)) {
-	error->zip_err = ZIP_ER_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)
 {
     char buf[BUFSIZE];
@@ -546,6 +444,40 @@
 
 
 static int
+copy_source(struct zip *za, struct zip_source *src, FILE *ft)
+{
+    char buf[BUFSIZE];
+    zip_int64_t n;
+    int ret;
+
+    if (zip_source_open(src) < 0) {
+	_zip_error_set_from_source(&za->error, src);
+	return -1;
+    }
+
+    ret = 0;
+    while ((n=zip_source_read(src, buf, sizeof(buf))) > 0) {
+	if (fwrite(buf, 1, n, ft) != (size_t)n) {
+	    _zip_error_set(&za->error, ZIP_ER_WRITE, errno);
+	    ret = -1;
+	    break;
+	}
+    }
+    
+    if (n < 0) {
+	if (ret == 0)
+	    _zip_error_set_from_source(&za->error, src);
+	ret = -1;
+    }	
+
+    zip_source_close(src);
+    
+    return ret;
+}
+
+
+
+static int
 write_cdir(struct zip *za, struct zip_cdir *cd, FILE *out)
 {
     off_t offset;
@@ -607,7 +539,7 @@
 
 
 
-static int
+int
 _zip_changed(struct zip *za, int *survivorsp)
 {
     int changed, i, survivors;
@@ -626,7 +558,8 @@
 	    survivors++;
     }
 
-    *survivorsp = survivors;
+    if (survivorsp)
+	*survivorsp = survivors;
 
     return changed;
 }
diff --git a/lib/zip_delete.c b/lib/zip_delete.c
index a0545e4..8178ebb 100644
--- a/lib/zip_delete.c
+++ b/lib/zip_delete.c
@@ -1,6 +1,6 @@
 /*
   zip_delete.c -- delete file from zip archive
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -38,13 +38,18 @@
 
 
 ZIP_EXTERN int
-zip_delete(struct zip *za, int idx)
+zip_delete(struct zip *za, zip_uint64_t idx)
 {
-    if (idx < 0 || idx >= za->nentry) {
+    if (idx >= za->nentry) {
 	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
 	return -1;
     }
 
+    if (ZIP_IS_RDONLY(za)) {
+	_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+	return -1;
+    }
+
     /* allow duplicate file names, because the file will
      * be removed directly afterwards */
     if (_zip_unchange(za, idx, 1) != 0)
diff --git a/lib/zip_dirent.c b/lib/zip_dirent.c
index a0bf9b0..adbf96c 100644
--- a/lib/zip_dirent.c
+++ b/lib/zip_dirent.c
@@ -1,6 +1,6 @@
 /*
   zip_dirent.c -- read directory entry (local or central), clean dirent
-  Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -45,7 +45,6 @@
 static time_t _zip_d2u_time(int, int);
 static char *_zip_readfpstr(FILE *, unsigned int, int, struct zip_error *);
 static char *_zip_readstr(unsigned char **, int, int, struct zip_error *);
-static void _zip_u2d_time(time_t, unsigned short *, unsigned short *);
 static void _zip_write2(unsigned short, FILE *);
 static void _zip_write4(unsigned int, FILE *);
 
@@ -213,13 +212,13 @@
 
 int
 _zip_dirent_read(struct zip_dirent *zde, FILE *fp,
-		 unsigned char **bufp, unsigned int *leftp, int local,
+		 unsigned char **bufp, zip_uint32_t *leftp, int local,
 		 struct zip_error *error)
 {
     unsigned char buf[CDENTRYSIZE];
     unsigned char *cur;
     unsigned short dostime, dosdate;
-    unsigned int size;
+    zip_uint32_t size;
 
     if (local)
 	size = LENTRYSIZE;
@@ -600,7 +599,7 @@
 
 
 
-static void
+void
 _zip_u2d_time(time_t time, unsigned short *dtime, unsigned short *ddate)
 {
     struct tm *tm;
diff --git a/lib/zip_entry_new.c b/lib/zip_entry_new.c
index 7059b1b..a22dd40 100644
--- a/lib/zip_entry_new.c
+++ b/lib/zip_entry_new.c
@@ -1,6 +1,6 @@
 /*
   zip_entry_new.c -- create and init struct zip_entry
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -51,7 +51,7 @@
 	}
     }
     else {
-	if (za->nentry >= za->nentry_alloc-1) {
+	if (za->nentry+1 >= za->nentry_alloc) {
 	    za->nentry_alloc += 16;
 	    za->entry = (struct zip_entry *)realloc(za->entry,
 						    sizeof(struct zip_entry)
diff --git a/lib/zip_err_str.c b/lib/zip_err_str.c
new file mode 100644
index 0000000..8fb6003
--- /dev/null
+++ b/lib/zip_err_str.c
@@ -0,0 +1,76 @@
+/*
+   This file was generated automatically by ./make_zip_err_str.sh
+   from ./zip.h; make changes there.
+ */
+
+#include "zipint.h"
+
+
+
+const char * const _zip_err_str[] = {
+    "No error",
+    "Multi-disk zip archives not supported",
+    "Renaming temporary file failed",
+    "Closing zip archive failed",
+    "Seek error",
+    "Read error",
+    "Write error",
+    "CRC error",
+    "Containing zip archive was closed",
+    "No such file",
+    "File already exists",
+    "Can't open file",
+    "Failure to create temporary file",
+    "Zlib error",
+    "Malloc failure",
+    "Entry has been changed",
+    "Compression method not supported",
+    "Premature EOF",
+    "Invalid argument",
+    "Not a zip archive",
+    "Internal error",
+    "Zip archive inconsistent",
+    "Can't remove file",
+    "Entry has been deleted",
+    "Encryption method not supported",
+    "Read-only archive", 
+    "No password provided",
+    "Wrong password provided",
+};
+
+const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]);
+
+#define N ZIP_ET_NONE
+#define S ZIP_ET_SYS
+#define Z ZIP_ET_ZLIB
+
+const int _zip_err_type[] = {
+    N,
+    N,
+    S,
+    S,
+    S,
+    S,
+    S,
+    N,
+    N,
+    N,
+    N,
+    S,
+    S,
+    Z,
+    N,
+    N,
+    N,
+    N,
+    N,
+    N,
+    N,
+    N,
+    S,
+    N,
+    N,
+    N, 
+    N,
+    N,
+};
diff --git a/lib/zip_error.c b/lib/zip_error.c
index aab7079..b8d907a 100644
--- a/lib/zip_error.c
+++ b/lib/zip_error.c
@@ -1,6 +1,6 @@
 /*
   zip_error.c -- struct zip_error helper functions
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -99,3 +99,14 @@
 	err->sys_err = se;
     }
 }
+
+
+
+void
+_zip_error_set_from_source(struct zip_error *err, struct zip_source *src)
+{
+    int ze, se;
+    
+    zip_source_error(src, &ze, &se);
+    _zip_error_set(err, ze, se);
+}
diff --git a/lib/zip_error_to_str.c b/lib/zip_error_to_str.c
index bdba41a..11a0cd2 100644
--- a/lib/zip_error_to_str.c
+++ b/lib/zip_error_to_str.c
@@ -1,6 +1,6 @@
 /*
   zip_error_to_str.c -- get string representation of zip error code
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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,7 +43,7 @@
 
 
 ZIP_EXTERN int
-zip_error_to_str(char *buf, size_t len, int ze, int se)
+zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se)
 {
     const char *zs, *ss;
 
diff --git a/lib/zip_fclose.c b/lib/zip_fclose.c
index 8709362..8a15feb 100644
--- a/lib/zip_fclose.c
+++ b/lib/zip_fclose.c
@@ -44,10 +44,8 @@
 {
     int i, ret;
     
-    if (zf->zstr)
-	inflateEnd(zf->zstr);
-    free(zf->buffer);
-    free(zf->zstr);
+    if (zf->src)
+	zip_source_free(zf->src);
 
     for (i=0; i<zf->za->nfile; i++) {
 	if (zf->za->file[i] == zf) {
@@ -60,11 +58,6 @@
     ret = 0;
     if (zf->error.zip_err)
 	ret = zf->error.zip_err;
-    else if ((zf->flags & ZIP_ZF_CRC) && (zf->flags & ZIP_ZF_EOF)) {
-	/* if EOF, compare CRC */
-	if (zf->crc_orig != zf->crc)
-	    ret = ZIP_ER_CRC;
-    }
 
     free(zf);
     return ret;
diff --git a/lib/zip_fdopen.c b/lib/zip_fdopen.c
new file mode 100644
index 0000000..09cdafd
--- /dev/null
+++ b/lib/zip_fdopen.c
@@ -0,0 +1,61 @@
+/*
+  zip_fdopen.c -- open read-only archive from file descriptor
+  Copyright (C) 2009 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 struct zip *
+zip_fdopen(int fd_orig, int flags, int *zep)
+{
+    int fd;
+    FILE *fp;
+
+    /* XXX: we dup here to avoid messing with the passed in fd.
+       We could not restore it to the original state in case of error. */
+
+    if ((fd=dup(fd_orig)) < 0) {
+	*zep = ZIP_ER_OPEN;
+	return NULL;
+    }
+
+    if ((fp=fdopen(fd, "rb")) == NULL) {
+	close(fd);
+	*zep = ZIP_ER_OPEN;
+	return NULL;
+    }
+
+    return _zip_open(NULL, fp, flags, ZIP_AFL_RDONLY, zep);
+}
diff --git a/lib/zip_fopen.c b/lib/zip_fopen.c
index 6e2f724..5a65eba 100644
--- a/lib/zip_fopen.c
+++ b/lib/zip_fopen.c
@@ -1,6 +1,6 @@
 /*
   zip_fopen.c -- open file in zip archive for reading
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -45,5 +45,5 @@
     if ((idx=zip_name_locate(za, fname, flags)) < 0)
 	return NULL;
 
-    return zip_fopen_index(za, idx, flags);
+    return zip_fopen_index_encrypted(za, idx, flags, za->default_password);
 }
diff --git a/lib/zip_fopen_encrypted.c b/lib/zip_fopen_encrypted.c
new file mode 100644
index 0000000..0a4b131
--- /dev/null
+++ b/lib/zip_fopen_encrypted.c
@@ -0,0 +1,50 @@
+/*
+  zip_fopen_encrypted.c -- open file for reading with password
+  Copyright (C) 1999-2009 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 struct zip_file *
+zip_fopen_encrypted(struct zip *za, const char *fname, int flags,
+		    const char *password)
+{
+    int idx;
+
+    if ((idx=zip_name_locate(za, fname, flags)) < 0)
+	return NULL;
+
+    return zip_fopen_index_encrypted(za, idx, flags, password);
+}
diff --git a/lib/zip_fopen_index.c b/lib/zip_fopen_index.c
index a330d69..3a58bbe 100644
--- a/lib/zip_fopen_index.c
+++ b/lib/zip_fopen_index.c
@@ -1,6 +1,6 @@
 /*
   zip_fopen_index.c -- open file in zip archive for reading by index
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -39,178 +39,10 @@
 
 #include "zipint.h"
 
-static struct zip_file *_zip_file_new(struct zip *za);
-
 
 
 ZIP_EXTERN struct zip_file *
-zip_fopen_index(struct zip *za, int fileno, int flags)
+zip_fopen_index(struct zip *za, zip_uint64_t fileno, int flags)
 {
-    int len, ret;
-    int zfflags;
-    struct zip_file *zf;
-
-    if ((fileno < 0) || (fileno >= za->nentry)) {
-	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
-	return NULL;
-    }
-
-    if ((flags & ZIP_FL_UNCHANGED) == 0
-	&& ZIP_ENTRY_DATA_CHANGED(za->entry+fileno)) {
-	_zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
-	return NULL;
-    }
-
-    if (fileno >= za->cdir->nentry) {
-	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
-	return NULL;
-    }
-
-    zfflags = 0;
-    switch (za->cdir->entry[fileno].comp_method) {
-    case ZIP_CM_STORE:
-	zfflags |= ZIP_ZF_CRC;
-	break;
-
-    case ZIP_CM_DEFLATE:
-	if ((flags & ZIP_FL_COMPRESSED) == 0)
-	    zfflags |= ZIP_ZF_CRC | ZIP_ZF_DECOMP;
-	break;
-    default:
-	if ((flags & ZIP_FL_COMPRESSED) == 0) {
-	    _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
-	    return NULL;
-	}
-	break;
-    }
-
-    zf = _zip_file_new(za);
-
-    zf->flags = zfflags;
-    /* zf->name = za->cdir->entry[fileno].filename; */
-    zf->method = za->cdir->entry[fileno].comp_method;
-    zf->bytes_left = za->cdir->entry[fileno].uncomp_size;
-    zf->cbytes_left = za->cdir->entry[fileno].comp_size;
-    zf->crc_orig = za->cdir->entry[fileno].crc;
-
-    if ((zf->fpos=_zip_file_get_offset(za, fileno)) == 0) {
-	zip_fclose(zf);
-	return NULL;
-    }
-    
-    if ((zf->flags & ZIP_ZF_DECOMP) == 0)
-	zf->bytes_left = zf->cbytes_left;
-    else {
-	if ((zf->buffer=(char *)malloc(BUFSIZE)) == NULL) {
-	    _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
-	    zip_fclose(zf);
-	    return NULL;
-	}
-
-	len = _zip_file_fillbuf(zf->buffer, BUFSIZE, zf);
-	if (len <= 0) {
-	    _zip_error_copy(&za->error, &zf->error);
-	    zip_fclose(zf);
-	return NULL;
-	}
-
-	if ((zf->zstr = (z_stream *)malloc(sizeof(z_stream))) == NULL) {
-	    _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
-	    zip_fclose(zf);
-	    return NULL;
-	}
-	zf->zstr->zalloc = Z_NULL;
-	zf->zstr->zfree = Z_NULL;
-	zf->zstr->opaque = NULL;
-	zf->zstr->next_in = (Bytef *)zf->buffer;
-	zf->zstr->avail_in = len;
-	
-	/* negative value to tell zlib that there is no header */
-	if ((ret=inflateInit2(zf->zstr, -MAX_WBITS)) != Z_OK) {
-	    _zip_error_set(&za->error, ZIP_ER_ZLIB, ret);
-	    zip_fclose(zf);
-	    return NULL;
-	}
-    }
-    
-    return zf;
-}
-
-
-
-int
-_zip_file_fillbuf(void *buf, size_t buflen, struct zip_file *zf)
-{
-    int i, j;
-
-    if (zf->error.zip_err != ZIP_ER_OK)
-	return -1;
-
-    if ((zf->flags & ZIP_ZF_EOF) || zf->cbytes_left <= 0 || buflen <= 0)
-	return 0;
-    
-    if (fseeko(zf->za->zp, zf->fpos, SEEK_SET) < 0) {
-	_zip_error_set(&zf->error, ZIP_ER_SEEK, errno);
-	return -1;
-    }
-    if (buflen < zf->cbytes_left)
-	i = buflen;
-    else
-	i = zf->cbytes_left;
-
-    j = fread(buf, 1, i, zf->za->zp);
-    if (j == 0) {
-	_zip_error_set(&zf->error, ZIP_ER_EOF, 0);
-	j = -1;
-    }
-    else if (j < 0)
-	_zip_error_set(&zf->error, ZIP_ER_READ, errno);
-    else {
-	zf->fpos += j;
-	zf->cbytes_left -= j;
-    }
-
-    return j;	
-}
-
-
-
-static struct zip_file *
-_zip_file_new(struct zip *za)
-{
-    struct zip_file *zf, **file;
-    int n;
-
-    if ((zf=(struct zip_file *)malloc(sizeof(struct zip_file))) == NULL) {
-	_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
-	return NULL;
-    }
-    
-    if (za->nfile >= za->nfile_alloc-1) {
-	n = za->nfile_alloc + 10;
-	file = (struct zip_file **)realloc(za->file,
-					   n*sizeof(struct zip_file *));
-	if (file == NULL) {
-	    _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
-	    free(zf);
-	    return NULL;
-	}
-	za->nfile_alloc = n;
-	za->file = file;
-    }
-
-    za->file[za->nfile++] = zf;
-
-    zf->za = za;
-    _zip_error_init(&zf->error);
-    zf->flags = 0;
-    zf->crc = crc32(0L, Z_NULL, 0);
-    zf->crc_orig = 0;
-    zf->method = -1;
-    zf->bytes_left = zf->cbytes_left = 0;
-    zf->fpos = 0;
-    zf->buffer = NULL;
-    zf->zstr = NULL;
-
-    return zf;
+    return zip_fopen_index_encrypted(za, fileno, flags, za->default_password);
 }
diff --git a/lib/zip_fopen_index_encrypted.c b/lib/zip_fopen_index_encrypted.c
new file mode 100644
index 0000000..2e617bf
--- /dev/null
+++ b/lib/zip_fopen_index_encrypted.c
@@ -0,0 +1,191 @@
+/*
+  zip_fopen_index_encrypted.c -- open file for reading by index w/ password
+  Copyright (C) 1999-2009 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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "zipint.h"
+
+static struct zip_file *_zip_file_new(struct zip *za);
+
+
+
+ZIP_EXTERN struct zip_file *
+zip_fopen_index_encrypted(struct zip *za, zip_uint64_t fileno, int flags,
+			  const char *password)
+{
+    struct zip_file *zf;
+    zip_compression_implementation comp_impl;
+    zip_encryption_implementation enc_impl;
+    struct zip_source *src, *s2;
+    zip_uint64_t start;
+    struct zip_stat st;
+
+    if (fileno >= za->nentry) {
+	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+	return NULL;
+    }
+
+    if ((flags & ZIP_FL_UNCHANGED) == 0
+	&& ZIP_ENTRY_DATA_CHANGED(za->entry+fileno)) {
+	_zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
+	return NULL;
+    }
+
+    if (fileno >= za->cdir->nentry) {
+	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+	return NULL;
+    }
+
+    if (flags & ZIP_FL_ENCRYPTED)
+	flags |= ZIP_FL_COMPRESSED;
+
+    zip_stat_index(za, fileno, flags, &st);
+
+    enc_impl = NULL;
+    if ((flags & ZIP_FL_ENCRYPTED) == 0) {
+	if (st.encryption_method != ZIP_EM_NONE) {
+	    if (password == NULL) {
+		_zip_error_set(&za->error, ZIP_ER_NOPASSWD, 0);
+		return NULL;
+	    }
+	    if ((enc_impl=zip_get_encryption_implementation(
+		     st.encryption_method)) == NULL) {
+		_zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
+		return NULL;
+	    }
+	}
+    }
+
+    comp_impl = NULL;
+    if ((flags & ZIP_FL_COMPRESSED) == 0) {
+	if (st.comp_method != ZIP_CM_STORE) {
+	    if ((comp_impl=zip_get_compression_implementation(
+		     st.comp_method)) == NULL) {
+		_zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
+		return NULL;
+	    }
+	}
+    }
+
+    if ((start=_zip_file_get_offset(za, fileno)) == 0)
+	return NULL;
+
+    if (st.comp_size == 0) {
+	if ((src=zip_source_buffer(za, NULL, 0, 0)) == NULL)
+	    return NULL;
+    }
+    else {
+	if ((src=_zip_source_file_or_p(za, NULL, za->zp, start, st.comp_size,
+				       0, &st)) == NULL)
+	    return NULL;
+	if (enc_impl) {
+	    if ((s2=enc_impl(za, src, ZIP_EM_TRAD_PKWARE, 0,
+			     password)) == NULL) {
+		zip_source_free(src);
+		/* XXX: set error (how?) */
+		return NULL;
+	    }
+	    src = s2;
+	}
+	if (comp_impl) {
+	    if ((s2=comp_impl(za, src, za->cdir->entry[fileno].comp_method,
+			      0)) == NULL) {
+		zip_source_free(src);
+		/* XXX: set error (how?) */
+		return NULL;
+	    }
+	    src = s2;
+	}
+	if ((flags & ZIP_FL_COMPRESSED) == 0
+	    || st.comp_method == ZIP_CM_STORE ) {
+	    if ((s2=zip_source_crc(za, src, 1)) == NULL) {
+		zip_source_free(src);
+		/* XXX: set error (how?) */
+		return NULL;
+	    }
+	    src = s2;
+	}
+    }
+
+    if (zip_source_open(src) < 0) {
+	_zip_error_set_from_source(&za->error, src);
+	zip_source_free(src);
+	return NULL;
+    }
+
+    zf = _zip_file_new(za);
+
+    zf->src = src;
+
+    return zf;
+}
+
+
+
+static struct zip_file *
+_zip_file_new(struct zip *za)
+{
+    struct zip_file *zf, **file;
+    int n;
+
+    if ((zf=(struct zip_file *)malloc(sizeof(struct zip_file))) == NULL) {
+	_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+	return NULL;
+    }
+    
+    if (za->nfile >= za->nfile_alloc-1) {
+	n = za->nfile_alloc + 10;
+	file = (struct zip_file **)realloc(za->file,
+					   n*sizeof(struct zip_file *));
+	if (file == NULL) {
+	    _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+	    free(zf);
+	    return NULL;
+	}
+	za->nfile_alloc = n;
+	za->file = file;
+    }
+
+    za->file[za->nfile++] = zf;
+
+    zf->za = za;
+    _zip_error_init(&zf->error);
+    zf->eof = 0;
+    zf->src = NULL;
+
+    return zf;
+}
diff --git a/lib/zip_fread.c b/lib/zip_fread.c
index 2a7fb42..8235c6d 100644
--- a/lib/zip_fread.c
+++ b/lib/zip_fread.c
@@ -37,12 +37,10 @@
 
 
 
-ZIP_EXTERN ssize_t
-zip_fread(struct zip_file *zf, void *outbuf, size_t toread)
+ZIP_EXTERN zip_int64_t
+zip_fread(struct zip_file *zf, void *outbuf, zip_uint64_t toread)
 {
-    int ret;
-    size_t out_before, len;
-    int i;
+    zip_int64_t n;
 
     if (!zf)
 	return -1;
@@ -50,81 +48,18 @@
     if (zf->error.zip_err != 0)
 	return -1;
 
-    if ((zf->flags & ZIP_ZF_EOF) || (toread == 0))
+    if (toread > ZIP_INT64_MAX) {
+	_zip_error_set(&zf->error, ZIP_ER_INVAL, 0);
+	return -1;
+    }
+
+    if ((zf->eof) || (toread == 0))
 	return 0;
 
-    if (zf->bytes_left == 0) {
-	zf->flags |= ZIP_ZF_EOF;
-	if (zf->flags & ZIP_ZF_CRC) {
-	    if (zf->crc != zf->crc_orig) {
-		_zip_error_set(&zf->error, ZIP_ER_CRC, 0);
-		return -1;
-	    }
-	}
-	return 0;
+    if ((n=zip_source_read(zf->src, outbuf, toread)) < 0) {
+	_zip_error_set_from_source(&zf->error, zf->src);
+	return -1;
     }
-    
-    if ((zf->flags & ZIP_ZF_DECOMP) == 0) {
-	ret = _zip_file_fillbuf(outbuf, toread, zf);
-	if (ret > 0) {
-	    if (zf->flags & ZIP_ZF_CRC)
-		zf->crc = crc32(zf->crc, (Bytef *)outbuf, ret);
-	    zf->bytes_left -= ret;
-	}
-	return ret;
-    }
-    
-    zf->zstr->next_out = (Bytef *)outbuf;
-    zf->zstr->avail_out = toread;
-    out_before = zf->zstr->total_out;
-    
-    /* endless loop until something has been accomplished */
-    for (;;) {
-	ret = inflate(zf->zstr, Z_SYNC_FLUSH);
 
-	switch (ret) {
-	case Z_STREAM_END:
-	    if (zf->zstr->total_out == out_before) {
-		if (zf->crc != zf->crc_orig) {
-		    _zip_error_set(&zf->error, ZIP_ER_CRC, 0);
-		    return -1;
-		}
-		else
-		    return 0;
-	    }
-
-	    /* fallthrough */
-
-	case Z_OK:
-	    len = zf->zstr->total_out - out_before;
-	    if (len >= zf->bytes_left || len >= toread) {
-		if (zf->flags & ZIP_ZF_CRC)
-		    zf->crc = crc32(zf->crc, (Bytef *)outbuf, len);
-		zf->bytes_left -= len;
-	        return len;
-	    }
-	    break;
-
-	case Z_BUF_ERROR:
-	    if (zf->zstr->avail_in == 0) {
-		i = _zip_file_fillbuf(zf->buffer, BUFSIZE, zf);
-		if (i == 0) {
-		    _zip_error_set(&zf->error, ZIP_ER_INCONS, 0);
-		    return -1;
-		}
-		else if (i < 0)
-		    return -1;
-		zf->zstr->next_in = (Bytef *)zf->buffer;
-		zf->zstr->avail_in = i;
-		continue;
-	    }
-	    /* fallthrough */
-	case Z_NEED_DICT:
-	case Z_DATA_ERROR:
-	case Z_STREAM_ERROR:
-	case Z_MEM_ERROR:
-	    _zip_error_set(&zf->error, ZIP_ER_ZLIB, ret);
-	    return -1;
-	}
-    }
+    return n;
 }
diff --git a/lib/zip_get_compression_implementation.c b/lib/zip_get_compression_implementation.c
new file mode 100644
index 0000000..8d4ccb6
--- /dev/null
+++ b/lib/zip_get_compression_implementation.c
@@ -0,0 +1,46 @@
+/*
+  zip_get_compression_implementation.c -- get compression implementation
+  Copyright (C) 2009 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 zip_compression_implementation
+zip_get_compression_implementation(zip_uint16_t cm)
+{
+    if (cm == ZIP_CM_DEFLATE)
+	return zip_source_deflate;
+    return NULL;
+}
diff --git a/lib/zip_get_encryption_implementation.c b/lib/zip_get_encryption_implementation.c
new file mode 100644
index 0000000..d83698c
--- /dev/null
+++ b/lib/zip_get_encryption_implementation.c
@@ -0,0 +1,46 @@
+/*
+  zip_get_encryption_implementation.c -- get encryption implementation
+  Copyright (C) 2009 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 zip_encryption_implementation
+zip_get_encryption_implementation(zip_uint16_t em)
+{
+    if (em == ZIP_EM_TRAD_PKWARE)
+	return zip_source_pkware;
+    return NULL;
+}
diff --git a/lib/zip_get_file_comment.c b/lib/zip_get_file_comment.c
index adace72..b9dacbe 100644
--- a/lib/zip_get_file_comment.c
+++ b/lib/zip_get_file_comment.c
@@ -38,9 +38,9 @@
 
 
 ZIP_EXTERN const char *
-zip_get_file_comment(struct zip *za, int idx, int *lenp, int flags)
+zip_get_file_comment(struct zip *za, zip_uint64_t idx, int *lenp, int flags)
 {
-    if (idx < 0 || idx >= za->nentry) {
+    if (idx >= za->nentry) {
 	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
 	return NULL;
     }
diff --git a/lib/zip_get_name.c b/lib/zip_get_name.c
index 8f5050b..531af50 100644
--- a/lib/zip_get_name.c
+++ b/lib/zip_get_name.c
@@ -38,7 +38,7 @@
 
 
 ZIP_EXTERN const char *
-zip_get_name(struct zip *za, int idx, int flags)
+zip_get_name(struct zip *za, zip_uint64_t idx, int flags)
 {
     return _zip_get_name(za, idx, flags, &za->error);
 }
@@ -46,9 +46,10 @@
 
 
 const char *
-_zip_get_name(struct zip *za, int idx, int flags, struct zip_error *error)
+_zip_get_name(struct zip *za, zip_uint64_t idx, int flags,
+	      struct zip_error *error)
 {
-    if (idx < 0 || idx >= za->nentry) {
+    if (idx >= za->nentry) {
 	_zip_error_set(error, ZIP_ER_INVAL, 0);
 	return NULL;
     }
diff --git a/lib/zip_new.c b/lib/zip_new.c
index 3e8ccee..7ce1237 100644
--- a/lib/zip_new.c
+++ b/lib/zip_new.c
@@ -65,6 +65,7 @@
     za->nfile = za->nfile_alloc = 0;
     za->file = NULL;
     za->flags = za->ch_flags = 0;
+    za->default_password = NULL;
     
     return za;
 }
diff --git a/lib/zip_open.c b/lib/zip_open.c
index a65974d..47f642b 100644
--- a/lib/zip_open.c
+++ b/lib/zip_open.c
@@ -1,6 +1,6 @@
 /*
-  zip_open.c -- open zip archive
-  Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner
+  zip_open.c -- open zip archive by name
+  Copyright (C) 1999-2009 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>
@@ -61,10 +61,6 @@
 zip_open(const char *fn, int flags, int *zep)
 {
     FILE *fp;
-    struct zip *za;
-    struct zip_cdir *cdir;
-    int i;
-    off_t len;
     
     switch (_zip_file_exists(fn, flags, zep)) {
     case -1:
@@ -80,7 +76,23 @@
 	return NULL;
     }
 
-    fseeko(fp, 0, SEEK_END);
+    return _zip_open(fn, fp, flags, 0, zep);
+}
+
+
+
+struct zip *
+_zip_open(const char *fn, FILE *fp, int flags, int aflags, int *zep)
+{
+    struct zip *za;
+    struct zip_cdir *cdir;
+    int i;
+    off_t len;
+
+    if (fseeko(fp, 0, SEEK_END) < 0) {
+	*zep = ZIP_ER_SEEK;
+	return NULL;
+    }
     len = ftello(fp);
 
     /* treat empty files as empty archives */
@@ -154,7 +166,7 @@
     struct zip_cdir *cd;
     unsigned char *cdp, **bufp;
     int i, comlen, nentry;
-    unsigned int left;
+    zip_uint32_t left;
 
     comlen = buf + buflen - eocd - EOCDLEN;
     if (comlen < 0) {
@@ -237,7 +249,7 @@
 	if (i == cd->nentry && left > 0) {
 	    /* Infozip extension for more than 64k entries:
 	       nentries wraps around, size indicates correct EOCD */
-	    _zip_cdir_grow(cd, cd->nentry+0x10000, error);
+	    _zip_cdir_grow(cd, cd->nentry+ZIP_UINT16_MAX, error);
 	}
 
 	if ((_zip_dirent_read(cd->entry+i, fp, bufp, &left, 0, error)) < 0) {
@@ -426,12 +438,16 @@
 	set_error(zep, &error, 0);
 	return NULL;
     }
-	
-    za->zn = strdup(fn);
-    if (!za->zn) {
-	_zip_free(za);
-	set_error(zep, NULL, ZIP_ER_MEMORY);
-	return NULL;
+
+    if (fn == NULL)
+	za->zn = NULL;
+    else {
+	za->zn = strdup(fn);
+	if (!za->zn) {
+	    _zip_free(za);
+	    set_error(zep, NULL, ZIP_ER_MEMORY);
+	    return NULL;
+	}
     }
     return za;
 }
diff --git a/lib/zip_rename.c b/lib/zip_rename.c
index 1d056bb..d78bbe8 100644
--- a/lib/zip_rename.c
+++ b/lib/zip_rename.c
@@ -1,6 +1,6 @@
 /*
   zip_rename.c -- rename file in zip archive
-  Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -40,16 +40,21 @@
 
 
 ZIP_EXTERN int
-zip_rename(struct zip *za, int idx, const char *name)
+zip_rename(struct zip *za, zip_uint64_t idx, const char *name)
 {
     const char *old_name;
     int old_is_dir, new_is_dir;
     
-    if (idx >= za->nentry || idx < 0 || name[0] == '\0') {
+    if (idx >= za->nentry || name[0] == '\0') {
 	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
 	return -1;
     }
 
+    if (ZIP_IS_RDONLY(za)) {
+	_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+	return -1;
+    }
+
     if ((old_name=zip_get_name(za, idx, 0)) == NULL)
 	return -1;
 								    
diff --git a/lib/zip_replace.c b/lib/zip_replace.c
index 6cdb80c..c444e78 100644
--- a/lib/zip_replace.c
+++ b/lib/zip_replace.c
@@ -1,6 +1,6 @@
 /*
   zip_replace.c -- replace file via callback function
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -38,9 +38,9 @@
 
 
 ZIP_EXTERN int
-zip_replace(struct zip *za, int idx, struct zip_source *source)
+zip_replace(struct zip *za, zip_uint64_t idx, struct zip_source *source)
 {
-    if (idx < 0 || idx >= za->nentry || source == NULL) {
+    if (idx >= za->nentry || source == NULL) {
 	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
 	return -1;
     }
@@ -54,11 +54,18 @@
 
 
 
-int
-_zip_replace(struct zip *za, int idx, const char *name,
+/* NOTE: Signed due to -1 on error.  See zip_add.c for more details. */
+
+zip_int64_t
+_zip_replace(struct zip *za, zip_uint64_t idx, const char *name,
 	     struct zip_source *source)
 {
-    if (idx == -1) {
+    if (ZIP_IS_RDONLY(za)) {
+	_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+	return -1;
+    }
+
+    if (idx == ZIP_UINT64_MAX) {
 	if (_zip_entry_new(za) == NULL)
 	    return -1;
 
diff --git a/lib/zip_set_archive_comment.c b/lib/zip_set_archive_comment.c
index 343fa54..3bb85d1 100644
--- a/lib/zip_set_archive_comment.c
+++ b/lib/zip_set_archive_comment.c
@@ -1,6 +1,6 @@
 /*
   zip_set_archive_comment.c -- set archive comment
-  Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 2006-2009 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>
@@ -50,6 +50,11 @@
 	return -1;
     }
 
+    if (ZIP_IS_RDONLY(za)) {
+	_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+	return -1;
+    }
+
     if (len > 0) {
 	if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL)
 	    return -1;
diff --git a/lib/zip_set_archive_flag.c b/lib/zip_set_archive_flag.c
index 720e1f3..e0e713a 100644
--- a/lib/zip_set_archive_flag.c
+++ b/lib/zip_set_archive_flag.c
@@ -1,6 +1,6 @@
 /*
   zip_get_archive_flag.c -- set archive global flag
-  Copyright (C) 2008 Dieter Baron and Thomas Klausner
+  Copyright (C) 2008-2009 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>
@@ -40,10 +40,30 @@
 ZIP_EXTERN int
 zip_set_archive_flag(struct zip *za, int flag, int value)
 {
+    unsigned int new_flags;
+    
     if (value)
-	za->ch_flags |= flag;
+	new_flags = za->ch_flags | flag;
     else
-	za->ch_flags &= ~flag;
+	new_flags = za->ch_flags & ~flag;
+
+    if (new_flags == za->ch_flags)
+	return 0;
+
+    if (ZIP_IS_RDONLY(za)) {
+	_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+	return -1;
+    }
+
+    if ((flag & ZIP_AFL_RDONLY) && value
+	&& (za->ch_flags & ZIP_AFL_RDONLY) == 0) {
+	if (_zip_changed(za, NULL)) {
+	    _zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
+	    return -1;
+	}
+    }
+
+    za->ch_flags = new_flags;
 
     return 0;
 }
diff --git a/lib/zip_set_default_password.c b/lib/zip_set_default_password.c
new file mode 100644
index 0000000..eb02c34
--- /dev/null
+++ b/lib/zip_set_default_password.c
@@ -0,0 +1,59 @@
+/*
+  zip_set_default_password.c -- set default password for decryption
+  Copyright (C) 2009 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 <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+
+
+
+ZIP_EXTERN int
+zip_set_default_password(struct zip *za, const char *passwd)
+{
+    if (za->default_password)
+	free(za->default_password);
+    
+    if (passwd) {
+	if ((za->default_password=strdup(passwd)) == NULL) {
+	    _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+	    return -1;
+	}
+    }
+    else
+	za->default_password = NULL;
+
+    return 0;
+}
diff --git a/lib/zip_set_file_comment.c b/lib/zip_set_file_comment.c
index bc1938e..6ae76a0 100644
--- a/lib/zip_set_file_comment.c
+++ b/lib/zip_set_file_comment.c
@@ -1,6 +1,6 @@
 /*
   zip_set_file_comment.c -- set comment for file in archive
-  Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 2006-2009 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>
@@ -40,17 +40,23 @@
 
 
 ZIP_EXTERN int
-zip_set_file_comment(struct zip *za, int idx, const char *comment, int len)
+zip_set_file_comment(struct zip *za, zip_uint64_t idx,
+		     const char *comment, int len)
 {
     char *tmpcom;
 
-    if (idx < 0 || idx >= za->nentry
+    if (idx >= za->nentry
 	|| len < 0 || len > MAXCOMLEN
 	|| (len > 0 && comment == NULL)) {
 	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
 	return -1;
     }
 
+    if (ZIP_IS_RDONLY(za)) {
+	_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+	return -1;
+    }
+
     if (len > 0) {
 	if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL)
 	    return -1;
diff --git a/lib/zip_set_name.c b/lib/zip_set_name.c
index 5c7da3d..2a90601 100644
--- a/lib/zip_set_name.c
+++ b/lib/zip_set_name.c
@@ -41,12 +41,12 @@
 
 
 int
-_zip_set_name(struct zip *za, int idx, const char *name)
+_zip_set_name(struct zip *za, zip_uint64_t idx, const char *name)
 {
     char *s;
-    int i;
+    zip_int64_t i;
     
-    if (idx < 0 || idx >= za->nentry || name == NULL) {
+    if (idx >= za->nentry || name == NULL) {
 	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
 	return -1;
     }
diff --git a/lib/zip_source_buffer.c b/lib/zip_source_buffer.c
index 1e9121c..af8bf19 100644
--- a/lib/zip_source_buffer.c
+++ b/lib/zip_source_buffer.c
@@ -1,6 +1,6 @@
 /*
   zip_source_buffer.c -- create zip data source from buffer
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -44,13 +44,12 @@
     int freep;
 };
 
-static ssize_t read_data(void *state, void *data, size_t len,
-			 enum zip_source_cmd cmd);
+static zip_int64_t read_data(void *, void *, zip_uint64_t, enum zip_source_cmd);
 
 
 
 ZIP_EXTERN struct zip_source *
-zip_source_buffer(struct zip *za, const void *data, off_t len, int freep)
+zip_source_buffer(struct zip *za, const void *data, zip_uint64_t len, int freep)
 {
     struct read_data *f;
     struct zip_source *zs;
@@ -58,7 +57,7 @@
     if (za == NULL)
 	return NULL;
 
-    if (len < 0 || (data == NULL && len > 0)) {
+    if (data == NULL && len > 0) {
 	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
 	return NULL;
     }
@@ -83,12 +82,12 @@
 
 
 
-static ssize_t
-read_data(void *state, void *data, size_t len, enum zip_source_cmd cmd)
+static zip_int64_t
+read_data(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
 {
     struct read_data *z;
     char *buf;
-    size_t n;
+    zip_uint64_t n;
 
     z = (struct read_data *)state;
     buf = (char *)data;
@@ -99,6 +98,8 @@
 	return 0;
 	
     case ZIP_SOURCE_READ:
+	/* XXX: return error if (len > ZIP_INT64_MAX) */
+
 	n = z->end - z->buf;
 	if (n > len)
 	    n = len;
@@ -125,6 +126,11 @@
 	    zip_stat_init(st);
 	    st->mtime = z->mtime;
 	    st->size = z->end - z->data;
+	    st->comp_size = st->size;
+	    st->comp_method = ZIP_CM_STORE;
+	    st->encryption_method = ZIP_EM_NONE;
+	    st->valid = ZIP_STAT_MTIME|ZIP_STAT_SIZE|ZIP_STAT_COMP_SIZE
+		|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;
 	    
 	    return sizeof(*st);
 	}
diff --git a/lib/zip_source_close.c b/lib/zip_source_close.c
new file mode 100644
index 0000000..882a199
--- /dev/null
+++ b/lib/zip_source_close.c
@@ -0,0 +1,54 @@
+/*
+  zip_source_close.c -- close zip_source (stop reading)
+  Copyright (C) 2009 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 void
+zip_source_close(struct zip_source *src)
+{
+    if (!src->is_open)
+	return;
+
+    if (src->src == NULL)
+	(void)src->cb.f(src->ud, NULL, 0, ZIP_SOURCE_CLOSE);
+    else {
+	(void)src->cb.l(src->src, src->ud, NULL, 0, ZIP_SOURCE_CLOSE);
+	zip_source_close(src->src);
+    }
+    
+    src->is_open = 0;
+}
diff --git a/lib/zip_source_crc.c b/lib/zip_source_crc.c
new file mode 100644
index 0000000..59e8a19
--- /dev/null
+++ b/lib/zip_source_crc.c
@@ -0,0 +1,159 @@
+/*
+  zip_source_crc.c -- pass-through source that calculates CRC32 and size
+  Copyright (C) 2009 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 <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+
+struct crc {
+    int eof;
+    int validate;
+    int e[2];
+    zip_uint64_t size;
+    zip_uint32_t crc;
+};
+
+static zip_int64_t crc_read(struct zip_source *, void *, void *
+			    , zip_uint64_t, enum zip_source_cmd);
+
+
+
+ZIP_EXTERN struct zip_source *
+zip_source_crc(struct zip *za, struct zip_source *src, int validate)
+{
+    struct crc *ctx;
+
+    if (src == NULL) {
+	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+	return NULL;
+    }
+
+    if ((ctx=(struct crc *)malloc(sizeof(*ctx))) == NULL) {
+	_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+	return NULL;
+    }
+
+    ctx->validate = validate;
+
+    return zip_source_layered(za, src, crc_read, ctx);
+}
+
+
+
+static zip_int64_t
+crc_read(struct zip_source *src, void *_ctx, void *data,
+	 zip_uint64_t len, enum zip_source_cmd cmd)
+{
+    struct crc *ctx;
+    zip_int64_t n;
+
+    ctx = (struct crc *)_ctx;
+
+    switch (cmd) {
+    case ZIP_SOURCE_OPEN:
+	ctx->eof = 0;
+	ctx->crc = crc32(0, NULL, 0);
+	ctx->size = 0;
+
+	return 0;
+
+    case ZIP_SOURCE_READ:
+	if (ctx->eof || len == 0)
+	    return 0;
+
+	if ((n=zip_source_read(src, data, len)) < 0)
+	    return ZIP_SOURCE_ERR_LOWER;
+
+	if (n == 0) {
+	    ctx->eof = 1;
+	    if (ctx->validate) {
+		struct zip_stat st;
+
+		if (zip_source_stat(src, &st) < 0)
+		    return ZIP_SOURCE_ERR_LOWER;
+
+		if ((st.valid & ZIP_STAT_CRC) && st.crc != ctx->crc) {
+		    ctx->e[0] = ZIP_ER_CRC;
+		    ctx->e[1] = 0;
+		    
+		    return -1;
+		}
+		if ((st.valid & ZIP_STAT_SIZE) && st.size != ctx->size) {
+		    ctx->e[0] = ZIP_ER_INCONS;
+		    ctx->e[1] = 0;
+		    
+		    return -1;
+		}
+	    }
+	}
+	else {
+	    ctx->size += n;
+	    ctx->crc = crc32(ctx->crc, data, n);
+	}
+	return n;
+
+    case ZIP_SOURCE_CLOSE:
+	return 0;
+
+    case ZIP_SOURCE_STAT:
+	{
+	    struct zip_stat *st;
+
+	    st = (struct zip_stat *)data;
+
+	    if (ctx->eof) {
+		/* XXX: Set comp_size, comp_method, encryption_method?
+		        After all, this only works for uncompressed data. */
+		st->size = ctx->size;
+		st->crc = ctx->crc;
+		st->valid |= ZIP_STAT_SIZE|ZIP_STAT_CRC;
+	    }
+	}
+	return 0;
+	
+    case ZIP_SOURCE_ERROR:
+	memcpy(data, ctx->e, sizeof(ctx->e));
+	return 0;
+
+    case ZIP_SOURCE_FREE:
+	free(ctx);
+	return 0;
+
+    default:
+	return -1;
+    }
+    
+}
diff --git a/lib/zip_source_deflate.c b/lib/zip_source_deflate.c
new file mode 100644
index 0000000..9e75b53
--- /dev/null
+++ b/lib/zip_source_deflate.c
@@ -0,0 +1,392 @@
+/*
+  zip_source_deflate.c -- deflate (de)compressoin routines
+  Copyright (C) 2009 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 <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+
+struct deflate {
+    int e[2];
+
+    int eof;
+    int mem_level;
+    zip_uint64_t size;
+    char buffer[BUFSIZE];
+    z_stream zstr;
+};
+
+static zip_int64_t compress_read(struct zip_source *, struct deflate *,
+				 void *, zip_uint64_t);
+static zip_int64_t decompress_read(struct zip_source *, struct deflate *,
+				   void *, zip_uint64_t);
+static zip_int64_t deflate_compress(struct zip_source *, void *, void *,
+				    zip_uint64_t, enum zip_source_cmd);
+static zip_int64_t deflate_decompress(struct zip_source *, void *, void *,
+				      zip_uint64_t, enum zip_source_cmd);
+static void deflate_free(struct deflate *);
+
+
+
+ZIP_EXTERN struct zip_source *
+zip_source_deflate(struct zip *za, struct zip_source *src,
+		   zip_uint16_t cm, int flags)
+{
+    struct deflate *ctx;
+    struct zip_source *s2;
+
+    if (src == NULL || cm != ZIP_CM_DEFLATE) {
+	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+	return NULL;
+    }
+
+    if ((ctx=(struct deflate *)malloc(sizeof(*ctx))) == NULL) {
+	_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+	return NULL;
+    }
+
+    ctx->e[0] = ctx->e[1] = 0;
+    ctx->eof = 0;
+    if (flags & ZIP_CODEC_ENCODE) {
+	if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
+	    ctx->mem_level = TORRENT_MEM_LEVEL;
+	else
+	    ctx->mem_level = MAX_MEM_LEVEL;
+    }
+
+    if ((s2=zip_source_layered(za, src,
+			       ((flags & ZIP_CODEC_ENCODE)
+				? deflate_compress : deflate_decompress),
+			       ctx)) == NULL) {
+	deflate_free(ctx);
+	return NULL;
+    }
+
+    return s2;
+}
+
+
+
+static zip_int64_t
+compress_read(struct zip_source *src, struct deflate *ctx,
+	      void *data, zip_uint64_t len)
+{
+    int end, ret;
+    zip_int64_t n;
+
+    if (ctx->e[0] != 0)
+	return -1;
+    
+    if (ctx->eof || (len == 0))
+	return 0;
+	
+    ctx->zstr.next_out = (Bytef *)data;
+    ctx->zstr.avail_out = len;
+
+    end = 0;
+    while (!end) {
+	ret = deflate(&ctx->zstr, ctx->eof ? Z_FINISH : 0);
+
+	switch (ret) {
+	case Z_OK:
+	case Z_STREAM_END:
+	    /* all ok */
+
+	    if (ctx->zstr.avail_out == 0
+		|| (ctx->eof && ctx->zstr.avail_in == 0))
+		end = 1;
+	    break;
+
+	case Z_BUF_ERROR:
+	    if (ctx->zstr.avail_in == 0) {
+		if (ctx->eof) {
+		    end = 1;
+		    break;
+		}
+
+		if ((n=zip_source_read(src, ctx->buffer,
+				       sizeof(ctx->buffer))) < 0) {
+		    zip_source_error(src, ctx->e, ctx->e+1);
+		    end = 1;
+		    break;
+		}
+		else if (n == 0) {
+		    ctx->eof = 1;
+		    ctx->size = ctx->zstr.total_in;
+		    /* XXX: check against stat of src? */
+		}
+		else {
+		    ctx->zstr.next_in = (Bytef *)ctx->buffer;
+		    ctx->zstr.avail_in = n;
+		}
+		continue;
+	    }
+	    /* fallthrough */
+	case Z_NEED_DICT:
+	case Z_DATA_ERROR:
+	case Z_STREAM_ERROR:
+	case Z_MEM_ERROR:
+	    ctx->e[0] = ZIP_ER_ZLIB;
+	    ctx->e[1] = ret;
+
+	    end = 1;
+	    break;
+	}
+    }
+
+    if (ctx->zstr.avail_out < len)
+	return len - ctx->zstr.avail_out;
+
+    return (ctx->e[0] == 0) ? 0 : -1;
+}
+
+
+
+static zip_int64_t
+decompress_read(struct zip_source *src, struct deflate *ctx,
+		void *data, zip_uint64_t len)
+{
+    int end, ret;
+    zip_int64_t n;
+
+    if (ctx->e[0] != 0)
+	return -1;
+    
+    if (ctx->eof || (len == 0))
+	return 0;
+	
+    ctx->zstr.next_out = (Bytef *)data;
+    ctx->zstr.avail_out = len;
+
+    end = 0;
+    while (!end && ctx->zstr.avail_out) {
+	ret = inflate(&ctx->zstr, Z_SYNC_FLUSH);
+
+	switch (ret) {
+	case Z_OK:
+	    break;
+	    
+	case Z_STREAM_END:
+	    ctx->eof = 1;
+	    end = 1;
+	    break;
+
+	case Z_BUF_ERROR:
+	    if (ctx->zstr.avail_in == 0) {
+		if (ctx->eof) {
+		    end = 1;
+		    break;
+		}
+
+		if ((n=zip_source_read(src, ctx->buffer,
+			    sizeof(ctx->buffer))) < 0) {
+		    zip_source_error(src, ctx->e, ctx->e+1);
+		    end = 1;
+		    break;
+		}
+		else if (n == 0)
+		    ctx->eof = 1;
+		else {
+		    ctx->zstr.next_in = (Bytef *)ctx->buffer;
+		    ctx->zstr.avail_in = n;
+		}
+		continue;
+	    }
+	    /* fallthrough */
+	case Z_NEED_DICT:
+	case Z_DATA_ERROR:
+	case Z_STREAM_ERROR:
+	case Z_MEM_ERROR:
+	    ctx->e[0] = ZIP_ER_ZLIB;
+	    ctx->e[1] = ret;
+	    end = 1;
+	    break;
+	}
+    }
+
+    if (ctx->zstr.avail_out < len)
+	return len - ctx->zstr.avail_out;
+
+    return (ctx->e[0] == 0) ? 0 : -1;
+}
+
+
+
+static zip_int64_t
+deflate_compress(struct zip_source *src, void *ud, void *data,
+		 zip_uint64_t len, enum zip_source_cmd cmd)
+{
+    struct deflate *ctx;
+    int ret;
+
+    ctx = (struct deflate *)ud;
+
+    switch (cmd) {
+    case ZIP_SOURCE_OPEN:
+	ctx->zstr.zalloc = Z_NULL;
+	ctx->zstr.zfree = Z_NULL;
+	ctx->zstr.opaque = NULL;
+	ctx->zstr.avail_in = 0;
+	ctx->zstr.avail_out = 0;
+
+	/* negative value to tell zlib not to write a header */
+	if ((ret=deflateInit2(&ctx->zstr, Z_BEST_COMPRESSION, Z_DEFLATED,
+			      -MAX_WBITS, ctx->mem_level,
+			      Z_DEFAULT_STRATEGY)) != Z_OK) {
+	    ctx->e[0] = ZIP_ER_ZLIB;
+	    ctx->e[1] = ret;
+	    return -1;
+	}
+
+	return 0;
+
+    case ZIP_SOURCE_READ:
+	return compress_read(src, ctx, data, len);
+
+    case ZIP_SOURCE_CLOSE:
+	deflateEnd(&ctx->zstr);
+	return 0;
+
+    case ZIP_SOURCE_STAT:
+    	{
+	    struct zip_stat *st;
+
+	    st = (struct zip_stat *)data;
+
+	    st->comp_method = ZIP_CM_DEFLATE;
+	    st->valid |= ZIP_STAT_COMP_METHOD;
+	    if (ctx->eof) {
+		st->comp_size = ctx->size;
+		st->valid |= ZIP_STAT_COMP_SIZE;
+	    }
+	    else
+		st->valid &= ~ZIP_STAT_COMP_SIZE;
+	}
+	return 0;
+
+    case ZIP_SOURCE_ERROR:
+	memcpy(data, ctx->e, sizeof(int)*2);
+	return sizeof(int)*2;
+
+    case ZIP_SOURCE_FREE:
+	deflate_free(ctx);
+	return 0;
+
+    default:
+	ctx->e[0] = ZIP_ER_INVAL;
+	ctx->e[1] = 0;
+	return -1;
+    }
+}
+
+
+
+static zip_int64_t
+deflate_decompress(struct zip_source *src, void *ud, void *data,
+		   zip_uint64_t len, enum zip_source_cmd cmd)
+{
+    struct deflate *ctx;
+    zip_int64_t n;
+    int ret;
+
+    ctx = (struct deflate *)ud;
+
+    switch (cmd) {
+    case ZIP_SOURCE_OPEN:
+	if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0)
+	    return ZIP_SOURCE_ERR_LOWER;
+
+	ctx->zstr.zalloc = Z_NULL;
+	ctx->zstr.zfree = Z_NULL;
+	ctx->zstr.opaque = NULL;
+	ctx->zstr.next_in = (Bytef *)ctx->buffer;
+	ctx->zstr.avail_in = n;
+
+	/* negative value to tell zlib that there is no header */
+	if ((ret=inflateInit2(&ctx->zstr, -MAX_WBITS)) != Z_OK) {
+	    ctx->e[0] = ZIP_ER_ZLIB;
+	    ctx->e[1] = ret;
+
+	    return -1;
+	}
+	return 0;
+
+    case ZIP_SOURCE_READ:
+	return decompress_read(src, ctx, data, len);
+
+    case ZIP_SOURCE_CLOSE:
+	inflateEnd(&ctx->zstr);
+	return 0;
+
+    case ZIP_SOURCE_STAT:
+	{
+	    struct zip_stat *st;
+
+	    st = (struct zip_stat *)data;
+
+	    st->comp_method = ZIP_CM_STORE;
+	    if (st->comp_size > 0 && st->size > 0)
+		st->comp_size = st->size;
+	}
+	return 0;
+
+    case ZIP_SOURCE_ERROR:
+	if (len < sizeof(int)*2)
+	    return -1;
+
+	memcpy(data, ctx->e, sizeof(int)*2);
+	return sizeof(int)*2;
+
+    case ZIP_SOURCE_FREE:
+	/* XXX: inflateEnd if close was not called */
+	free(ctx);
+	return 0;
+
+    default:
+	ctx->e[0] = ZIP_ER_INVAL;
+	ctx->e[1] = 0;
+	return -1;
+    }
+    
+}
+
+
+
+static void
+deflate_free(struct deflate *ctx)
+{
+    /* XXX: deflateEnd if close was not called */
+    free(ctx);
+}
diff --git a/lib/zip_source_error.c b/lib/zip_source_error.c
new file mode 100644
index 0000000..db9265f
--- /dev/null
+++ b/lib/zip_source_error.c
@@ -0,0 +1,86 @@
+/*
+  zip_source_error.c -- get last error from zip_source
+  Copyright (C) 2009 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 void
+zip_source_error(struct zip_source *src, int *ze, int *se)
+{
+    int e[2];
+
+    if (src->src == NULL) {
+    }
+    else {
+	switch (src->error_source) {
+	case ZIP_LES_NONE:
+	    if (src->src == NULL) {
+		if (src->cb.f(src->ud, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) {
+		    e[0] = ZIP_ER_INTERNAL;
+		    e[1] = 0;
+		}
+	    }
+	    else
+		e[0] = e[1] = 0;
+	    break;
+
+	case ZIP_LES_INVAL:
+	    e[0] = ZIP_ER_INVAL;
+	    e[1] = 0;
+	    break;
+
+	case ZIP_LES_LOWER:
+	    return zip_source_error(src->src, ze, se);
+
+	case ZIP_LES_UPPER:
+	    if (src->cb.l(src->src, src->ud, e, sizeof(e),
+			  ZIP_SOURCE_ERROR) < 0) {
+		e[0] = ZIP_ER_INTERNAL;
+		e[1] = 0;
+	    }
+	    break;
+
+	default:
+	    e[0] = ZIP_ER_INTERNAL;
+	    e[1] = 0;
+	}
+    }
+
+    if (ze)
+	*ze = e[0];
+    if (se)
+	*se = e[1];
+}
diff --git a/lib/zip_source_file.c b/lib/zip_source_file.c
index eb1129a..79c8ee5 100644
--- a/lib/zip_source_file.c
+++ b/lib/zip_source_file.c
@@ -1,6 +1,6 @@
 /*
   zip_source_file.c -- create data source from file
-  Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -41,15 +41,16 @@
 
 
 ZIP_EXTERN struct zip_source *
-zip_source_file(struct zip *za, const char *fname, off_t start, off_t len)
+zip_source_file(struct zip *za, const char *fname, zip_uint64_t start,
+		zip_int64_t len)
 {
     if (za == NULL)
 	return NULL;
 
-    if (fname == NULL || start < 0 || len < -1) {
+    if (fname == NULL || len < -1) {
 	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
 	return NULL;
     }
 
-    return _zip_source_file_or_p(za, fname, NULL, start, len);
+    return _zip_source_file_or_p(za, fname, NULL, start, len, 1, NULL);
 }
diff --git a/lib/zip_source_filep.c b/lib/zip_source_filep.c
index 5373934..5b7e0c0 100644
--- a/lib/zip_source_filep.c
+++ b/lib/zip_source_filep.c
@@ -1,6 +1,6 @@
 /*
   zip_source_filep.c -- create data source from FILE *
-  Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -44,19 +44,23 @@
 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 */
-    off_t remain;	/* bytes remaining to be copied */
+    int closep;		/* close f */
+    struct zip_stat st;	/* stat information passed in */
+
+    zip_uint64_t off;	/* start offset of */
+    zip_int64_t len;	/* length of data to copy */
+    zip_int64_t remain;	/* bytes remaining to be copied */
     int e[2];		/* error codes */
 };
 
-static ssize_t read_file(void *state, void *data, size_t len,
+static zip_int64_t read_file(void *state, void *data, zip_uint64_t len,
 		     enum zip_source_cmd cmd);
 
 
 
 ZIP_EXTERN struct zip_source *
-zip_source_filep(struct zip *za, FILE *file, off_t start, off_t len)
+zip_source_filep(struct zip *za, FILE *file, zip_uint64_t start,
+		 zip_int64_t len)
 {
     if (za == NULL)
 	return NULL;
@@ -66,14 +70,15 @@
 	return NULL;
     }
 
-    return _zip_source_file_or_p(za, NULL, file, start, len);
+    return _zip_source_file_or_p(za, NULL, file, start, len, 1, NULL);
 }
 
 
 
 struct zip_source *
 _zip_source_file_or_p(struct zip *za, const char *fname, FILE *file,
-		      off_t start, off_t len)
+		      zip_uint64_t start, zip_int64_t len, int closep,
+		      const struct zip_stat *st)
 {
     struct read_file *f;
     struct zip_source *zs;
@@ -99,7 +104,12 @@
     f->f = file;
     f->off = start;
     f->len = (len ? len : -1);
-    
+    f->closep = f->fname ? 1 : closep;
+    if (st)
+	memcpy(&f->st, st, sizeof(f->st));
+    else
+	zip_stat_init(&f->st);
+
     if ((zs=zip_source_function(za, read_file, f)) == NULL) {
 	free(f);
 	return NULL;
@@ -110,8 +120,8 @@
 
 
 
-static ssize_t
-read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd)
+static zip_int64_t
+read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
 {
     struct read_file *z;
     char *buf;
@@ -130,20 +140,33 @@
 	    }
 	}
 
-	if (fseeko(z->f, z->off, SEEK_SET) < 0) {
-	    z->e[0] = ZIP_ER_SEEK;
-	    z->e[1] = errno;
-	    return -1;
+	if (z->closep) {
+	    if (fseeko(z->f, (off_t)z->off, SEEK_SET) < 0) {
+		z->e[0] = ZIP_ER_SEEK;
+		z->e[1] = errno;
+		return -1;
+	    }
 	}
 	z->remain = z->len;
 	return 0;
 	
     case ZIP_SOURCE_READ:
+	/* XXX: return INVAL if len > size_t max */
 	if (z->remain != -1)
 	    n = len > z->remain ? z->remain : len;
 	else
 	    n = len;
-	
+
+	if (!z->closep) {
+	    /* we might share this file with others, so let's be save */
+	    if (fseeko(z->f, (off_t)(z->off + z->len-z->remain),
+		       SEEK_SET) < 0) {
+		z->e[0] = ZIP_ER_SEEK;
+		z->e[1] = errno;
+		return -1;
+	    }
+	}
+
 	if ((i=fread(buf, 1, n, z->f)) < 0) {
 	    z->e[0] = ZIP_ER_READ;
 	    z->e[1] = errno;
@@ -164,34 +187,42 @@
 
     case ZIP_SOURCE_STAT:
         {
-	    struct zip_stat *st;
-	    struct stat fst;
-	    int err;
+	    if (len < sizeof(z->st))
+		return -1;
+
+	    if (z->st.valid != 0)
+		memcpy(data, &z->st, sizeof(z->st));
+	    else {
+		struct zip_stat *st;
+		struct stat fst;
+		int err;
 	    
-	    if (len < sizeof(*st))
-		return -1;
+		if (z->f)
+		    err = fstat(fileno(z->f), &fst);
+		else
+		    err = stat(z->fname, &fst);
 
-	    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;
+		}
 
-	    if (err != 0) {
-		z->e[0] = ZIP_ER_READ; /* best match */
-		z->e[1] = errno;
-		return -1;
+		st = (struct zip_stat *)data;
+		
+		zip_stat_init(st);
+		st->mtime = fst.st_mtime;
+		st->valid |= ZIP_STAT_MTIME;
+		if (z->len != -1) {
+		    st->size = z->len;
+		    st->valid |= ZIP_STAT_SIZE;
+		}
+		else if ((fst.st_mode&S_IFMT) == S_IFREG) {
+		    st->size = fst.st_size;
+		    st->valid |= ZIP_STAT_SIZE;
+		}
 	    }
-
-	    st = (struct zip_stat *)data;
-
-	    zip_stat_init(st);
-	    st->mtime = fst.st_mtime;
-	    if (z->len != -1)
-		st->size = z->len;
-	    else if ((fst.st_mode&S_IFMT) == S_IFREG)
-		st->size = fst.st_size;
-
-	    return sizeof(*st);
+	    return sizeof(z->st);
 	}
 
     case ZIP_SOURCE_ERROR:
@@ -203,7 +234,7 @@
 
     case ZIP_SOURCE_FREE:
 	free(z->fname);
-	if (z->f)
+	if (z->closep && z->f)
 	    fclose(z->f);
 	free(z);
 	return 0;
diff --git a/lib/zip_source_free.c b/lib/zip_source_free.c
index 7a1632f..b1e7840 100644
--- a/lib/zip_source_free.c
+++ b/lib/zip_source_free.c
@@ -1,6 +1,6 @@
 /*
   zip_source_free.c -- free zip data source
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -40,12 +40,20 @@
 
 
 ZIP_EXTERN void
-zip_source_free(struct zip_source *source)
+zip_source_free(struct zip_source *src)
 {
-    if (source == NULL)
+    if (src == NULL)
 	return;
 
-    (void)source->f(source->ud, NULL, 0, ZIP_SOURCE_FREE);
+    if (src->is_open)
+	zip_source_close(src);
 
-    free(source);
+    if (src->src == NULL)
+	(void)src->cb.f(src->ud, NULL, 0, ZIP_SOURCE_FREE);
+    else {
+	(void)src->cb.l(src->src, src->ud, NULL, 0, ZIP_SOURCE_FREE);
+	zip_source_free(src->src);
+    }
+
+    free(src);
 }
diff --git a/lib/zip_source_function.c b/lib/zip_source_function.c
index 91b183c..cb92e33 100644
--- a/lib/zip_source_function.c
+++ b/lib/zip_source_function.c
@@ -1,6 +1,6 @@
 /*
   zip_source_function.c -- create zip data source from callback function
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -47,13 +47,32 @@
     if (za == NULL)
 	return NULL;
 
-    if ((zs=(struct zip_source *)malloc(sizeof(*zs))) == NULL) {
+    if ((zs=_zip_source_new(za)) == NULL)
+	return NULL;
+
+    zs->cb.f = zcb;
+    zs->ud = ud;
+    
+    return zs;
+}
+
+
+
+struct zip_source *
+_zip_source_new(struct zip *za)
+{
+    struct zip_source *src;
+
+    if ((src=(struct zip_source *)malloc(sizeof(*src))) == NULL) {
 	_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
 	return NULL;
     }
 
-    zs->f = zcb;
-    zs->ud = ud;
-    
-    return zs;
+    src->src = NULL;
+    src->cb.f = NULL;
+    src->ud = NULL;
+    src->error_source = ZIP_LES_NONE;
+    src->is_open = 0;
+
+    return src;
 }
diff --git a/lib/zip_source_layered.c b/lib/zip_source_layered.c
new file mode 100644
index 0000000..9bdf3c5
--- /dev/null
+++ b/lib/zip_source_layered.c
@@ -0,0 +1,59 @@
+/*
+  zip_source_layered.c -- create layered source
+  Copyright (C) 2009 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 <stdlib.h>
+
+#include "zipint.h"
+
+
+
+ZIP_EXTERN struct zip_source *
+zip_source_layered(struct zip *za, struct zip_source *src,
+		   zip_source_layered_callback cb, void *ud)
+{
+    struct zip_source *zs;
+
+    if (za == NULL)
+	return NULL;
+
+    if ((zs=_zip_source_new(za)) == NULL)
+	return NULL;
+
+    zs->src = src;
+    zs->cb.l = cb;
+    zs->ud = ud;
+    
+    return zs;
+}
diff --git a/lib/zip_source_open.c b/lib/zip_source_open.c
new file mode 100644
index 0000000..a279e20
--- /dev/null
+++ b/lib/zip_source_open.c
@@ -0,0 +1,76 @@
+/*
+  zip_source_open.c -- open zip_source (prepare for reading)
+  Copyright (C) 2009 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_source_open(struct zip_source *src)
+{
+    zip_int64_t ret;
+
+    if (src->is_open) {
+	src->error_source = ZIP_LES_INVAL;
+	return -1;
+    }
+
+    if (src->src == NULL) {
+	if (src->cb.f(src->ud, NULL, 0, ZIP_SOURCE_OPEN) < 0)
+	    return -1;
+    }
+    else {
+	if (zip_source_open(src->src) < 0) {
+	    src->error_source = ZIP_LES_LOWER;
+	    return -1;
+	}
+
+	ret = src->cb.l(src->src, src->ud, NULL, 0, ZIP_SOURCE_OPEN);
+	
+	if (ret < 0) {
+	    (void)zip_source_close(src->src);
+	    
+	    if (ret == ZIP_SOURCE_ERR_LOWER)
+		src->error_source = ZIP_LES_LOWER;
+	    else
+		src->error_source = ZIP_LES_UPPER;
+	    return -1;
+	}
+    }
+
+    src->is_open = 1;
+    
+    return 0;
+}
diff --git a/lib/zip_source_pkware.c b/lib/zip_source_pkware.c
new file mode 100644
index 0000000..c1f3e42
--- /dev/null
+++ b/lib/zip_source_pkware.c
@@ -0,0 +1,241 @@
+/*
+  zip_source_pkware.c -- Traditional PKWARE de/encryption routines
+  Copyright (C) 2009 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 <stdlib.h>
+#include <string.h>
+
+#include "zipint.h"
+
+struct trad_pkware {
+    int e[2];
+
+    zip_uint32_t key[3];
+};
+
+#define HEADERLEN	12
+#define KEY0		305419896
+#define KEY1		591751049
+#define KEY2		878082192
+
+static const uLongf *crc = NULL;
+
+#define CRC32(c, b) (crc[((c) ^ (b)) & 0xff] ^ ((c) >> 8))
+
+
+
+static void decrypt(struct trad_pkware *, zip_uint8_t *,
+		    const zip_uint8_t *, zip_uint64_t, int);
+static int decrypt_header(struct zip_source *, struct trad_pkware *);
+static zip_int64_t pkware_decrypt(struct zip_source *, void *, void *,
+				  zip_uint64_t, enum zip_source_cmd);
+static void pkware_free(struct trad_pkware *);
+
+
+
+ZIP_EXTERN struct zip_source *
+zip_source_pkware(struct zip *za, struct zip_source *src,
+		  zip_uint16_t em, int flags, const char *password)
+{
+    struct trad_pkware *ctx;
+    struct zip_source *s2;
+
+    if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) {
+	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+	return NULL;
+    }
+    if (flags & ZIP_CODEC_ENCODE) {
+	_zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
+	return NULL;
+    }
+
+    if (crc == NULL)
+	crc = get_crc_table();
+
+    if ((ctx=(struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
+	_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+	return NULL;
+    }
+
+    ctx->e[0] = ctx->e[1] = 0;
+
+    ctx->key[0] = KEY0;
+    ctx->key[1] = KEY1;
+    ctx->key[2] = KEY2;
+    decrypt(ctx, NULL, (const zip_uint8_t *)password, strlen(password), 1);
+
+    if ((s2=zip_source_layered(za, src, pkware_decrypt, ctx)) == NULL) {
+	pkware_free(ctx);
+	return NULL;
+    }
+
+    return s2;
+}
+
+
+
+static void
+decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in,
+	zip_uint64_t len, int update_only)
+{
+    zip_uint16_t tmp;
+    zip_uint64_t i;
+    Bytef b;
+
+    for (i=0; i<len; i++) {
+	b = in[i];
+
+	if (!update_only) {
+	    /* decrypt next byte */
+	    tmp = ctx->key[2] | 2;
+	    tmp = (tmp * (tmp ^ 1)) >> 8;
+	    b ^= tmp;
+	}
+
+	/* store cleartext */
+	if (out)
+	    out[i] = b;
+
+	/* update keys */
+	ctx->key[0] = CRC32(ctx->key[0], b);
+	ctx->key[1] = (ctx->key[1] + (ctx->key[0] & 0xff)) * 134775813 + 1;
+	b = ctx->key[1] >> 24;
+	ctx->key[2] = CRC32(ctx->key[2], b);
+    }
+}
+
+
+
+static int
+decrypt_header(struct zip_source *src, struct trad_pkware *ctx)
+{
+    zip_uint8_t header[HEADERLEN];
+    struct zip_stat st;
+    zip_int64_t n;
+    unsigned short dostime, dosdate;
+
+    if ((n=zip_source_read(src, header, HEADERLEN)) < 0) {
+	zip_source_error(src, ctx->e, ctx->e+1);
+	return -1;
+    }
+    
+    if (n != HEADERLEN) {
+	ctx->e[0] = ZIP_ER_EOF;
+	ctx->e[1] = 0;
+	return -1;
+    }
+
+    decrypt(ctx, header, header, HEADERLEN, 0);
+
+    if (zip_source_stat(src, &st) < 0) {
+	/* stat failed, skip password validation */
+	return 0;
+    }
+
+    _zip_u2d_time(st.mtime, &dostime, &dosdate);
+
+    if (header[HEADERLEN-1] != st.crc>>24
+	&& header[HEADERLEN-1] != dostime>>8) {
+	ctx->e[0] = ZIP_ER_WRONGPASSWD;
+	ctx->e[1] = 0;
+	return -1;
+    }
+
+    return 0;
+}
+
+
+
+static zip_int64_t
+pkware_decrypt(struct zip_source *src, void *ud, void *data,
+	       zip_uint64_t len, enum zip_source_cmd cmd)
+{
+    struct trad_pkware *ctx;
+    zip_int64_t n;
+
+    ctx = (struct trad_pkware *)ud;
+
+    switch (cmd) {
+    case ZIP_SOURCE_OPEN:
+	if (decrypt_header(src, ctx) < 0)
+	    return -1;
+	return 0;
+
+    case ZIP_SOURCE_READ:
+	if ((n=zip_source_read(src, data, len)) < 0)
+	    return ZIP_SOURCE_ERR_LOWER;
+
+	decrypt(ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n,
+		0);
+	return n;
+
+    case ZIP_SOURCE_CLOSE:
+	return 0;
+
+    case ZIP_SOURCE_STAT:
+	{
+	    struct zip_stat *st;
+
+	    st = (struct zip_stat *)data;
+
+	    st->encryption_method = ZIP_EM_NONE;
+	    st->valid |= ZIP_STAT_ENCRYPTION_METHOD;
+	    /* XXX: deduce HEADERLEN from size for uncompressed */
+	    if (st->valid & ZIP_STAT_COMP_SIZE)
+		st->comp_size -= HEADERLEN;
+	}
+	return 0;
+
+    case ZIP_SOURCE_ERROR:
+	memcpy(data, ctx->e, sizeof(int)*2);
+	return sizeof(int)*2;
+
+    case ZIP_SOURCE_FREE:
+	pkware_free(ctx);
+	return 0;
+
+    default:
+	ctx->e[0] = ZIP_ER_INVAL;
+	ctx->e[1] = 0;
+	return -1;
+    }
+}
+
+
+
+static void
+pkware_free(struct trad_pkware *ctx)
+{
+    free(ctx);
+}
diff --git a/lib/zip_source_pop.c b/lib/zip_source_pop.c
new file mode 100644
index 0000000..88d37da
--- /dev/null
+++ b/lib/zip_source_pop.c
@@ -0,0 +1,63 @@
+/*
+  zip_source_pop.c -- pop top layer from zip data source
+  Copyright (C) 2009 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 <stdlib.h>
+
+#include "zipint.h"
+
+
+
+ZIP_EXTERN struct zip_source *
+zip_source_pop(struct zip_source *src)
+{
+    struct zip_source *lower;
+
+    if (src == NULL)
+	return NULL;
+
+    lower = src->src;
+
+    if (lower == NULL)
+	zip_source_free(src);
+    else {
+	if (src->is_open)
+	    (void)src->cb.l(src, src->ud, NULL, 0, ZIP_SOURCE_CLOSE);
+	(void)src->cb.l(src, src->ud, NULL, 0, ZIP_SOURCE_FREE);
+	
+	free(src);
+    }
+
+    return lower;
+}
diff --git a/lib/zip_source_read.c b/lib/zip_source_read.c
new file mode 100644
index 0000000..432243b
--- /dev/null
+++ b/lib/zip_source_read.c
@@ -0,0 +1,64 @@
+/*
+  zip_source_read.c -- read data from zip_source
+  Copyright (C) 2009 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 zip_int64_t
+zip_source_read(struct zip_source *src, void *data, zip_uint64_t len)
+{
+    zip_int64_t ret;
+
+    if (!src->is_open || len > ZIP_INT64_MAX || (len > 0 && data == NULL)) {
+	src->error_source = ZIP_LES_INVAL;
+	return -1;
+    }
+
+    if (src->src == NULL)
+	return src->cb.f(src->ud, data, len, ZIP_SOURCE_READ);
+
+    ret = src->cb.l(src->src, src->ud, data, len, ZIP_SOURCE_READ);
+
+    if (ret < 0) {
+	if (ret == ZIP_SOURCE_ERR_LOWER)
+	    src->error_source = ZIP_LES_LOWER;
+	else
+	    src->error_source = ZIP_LES_UPPER;
+	return -1;
+    }
+    
+    return ret;
+}
diff --git a/lib/zip_source_stat.c b/lib/zip_source_stat.c
new file mode 100644
index 0000000..2166074
--- /dev/null
+++ b/lib/zip_source_stat.c
@@ -0,0 +1,72 @@
+/*
+  zip_source_stat.c -- get meta information from zip_source
+  Copyright (C) 2009 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_source_stat(struct zip_source *src, struct zip_stat *st)
+{
+    zip_int64_t ret;
+
+    if (st == NULL) {
+	src->error_source = ZIP_LES_INVAL;
+	return -1;
+    }
+
+    if (src->src == NULL) {
+	if (src->cb.f(src->ud, st, sizeof(*st), ZIP_SOURCE_STAT) < 0)
+	    return -1;
+	return 0;
+    }
+
+    if (zip_source_stat(src->src, st) < 0) {
+	src->error_source = ZIP_LES_LOWER;
+	return -1;
+    }
+
+    ret = src->cb.l(src->src, src->ud, st, sizeof(*st), ZIP_SOURCE_STAT);
+
+    if (ret < 0) {
+	if (ret == ZIP_SOURCE_ERR_LOWER)
+	    src->error_source = ZIP_LES_LOWER;
+	else
+	    src->error_source = ZIP_LES_UPPER;
+	return -1;
+    }
+    
+    return 0;
+}
diff --git a/lib/zip_source_zip.c b/lib/zip_source_zip.c
index 3eef552..2b9061f 100644
--- a/lib/zip_source_zip.c
+++ b/lib/zip_source_zip.c
@@ -1,6 +1,6 @@
 /*
   zip_source_zip.c -- create data source from zip file
-  Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -41,17 +41,18 @@
 struct read_zip {
     struct zip_file *zf;
     struct zip_stat st;
-    off_t off, len;
+    zip_uint64_t off;
+    zip_int64_t len;
 };
 
-static ssize_t read_zip(void *st, void *data, size_t len,
+static zip_int64_t read_zip(void *st, void *data, zip_uint64_t len,
 			enum zip_source_cmd cmd);
 
 
 
 ZIP_EXTERN struct zip_source *
-zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags,
-	       off_t start, off_t len)
+zip_source_zip(struct zip *za, struct zip *srcza, zip_uint64_t srcidx,
+	       int flags, zip_uint64_t start, zip_int64_t len)
 {
     struct zip_error error;
     struct zip_source *zs;
@@ -62,7 +63,7 @@
     if (za == NULL)
 	return NULL;
 
-    if (srcza == NULL || start < 0 || len < -1 || srcidx < 0 || srcidx >= srcza->nentry) {
+    if (srcza == NULL || len < -1 || srcidx < 0 || srcidx >= srcza->nentry) {
 	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
 	return NULL;
     }
@@ -115,12 +116,13 @@
 
 
 
-static ssize_t
-read_zip(void *state, void *data, size_t len, enum zip_source_cmd cmd)
+static zip_int64_t
+read_zip(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd)
 {
     struct read_zip *z;
     char b[8192], *buf;
-    int i, n;
+    int i;
+    zip_uint64_t n;
 
     z = (struct read_zip *)state;
     buf = (char *)data;
diff --git a/lib/zip_stat_index.c b/lib/zip_stat_index.c
index 60558e4..0e15b55 100644
--- a/lib/zip_stat_index.c
+++ b/lib/zip_stat_index.c
@@ -1,6 +1,6 @@
 /*
   zip_stat_index.c -- get information about file by index
-  Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -38,11 +38,12 @@
 
 
 ZIP_EXTERN int
-zip_stat_index(struct zip *za, int index, int flags, struct zip_stat *st)
+zip_stat_index(struct zip *za, zip_uint64_t index, int flags,
+	       struct zip_stat *st)
 {
     const char *name;
     
-    if (index < 0 || index >= za->nentry) {
+    if (index >= za->nentry) {
 	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
 	return -1;
     }
@@ -53,8 +54,7 @@
 
     if ((flags & ZIP_FL_UNCHANGED) == 0
 	&& ZIP_ENTRY_DATA_CHANGED(za->entry+index)) {
-	if (za->entry[index].source->f(za->entry[index].source->ud,
-				     st, sizeof(*st), ZIP_SOURCE_STAT) < 0) {
+	if (zip_source_stat(za->entry[index].source, st) < 0) {
 	    _zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
 	    return -1;
 	}
@@ -64,7 +64,9 @@
 	    _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
 	    return -1;
 	}
-	
+
+	zip_stat_init(st);
+
 	st->crc = za->cdir->entry[index].crc;
 	st->size = za->cdir->entry[index].uncomp_size;
 	st->mtime = za->cdir->entry[index].last_mod;
@@ -80,11 +82,13 @@
 	}
 	else
 	    st->encryption_method = ZIP_EM_NONE;
-	/* st->bitflags = za->cdir->entry[index].bitflags; */
+	st->valid = ZIP_STAT_CRC|ZIP_STAT_SIZE|ZIP_STAT_MTIME
+	    |ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;
     }
 
     st->index = index;
     st->name = name;
+    st->valid |= ZIP_STAT_INDEX|ZIP_STAT_NAME;
     
     return 0;
 }
diff --git a/lib/zip_stat_init.c b/lib/zip_stat_init.c
index 133ad30..d17613b 100644
--- a/lib/zip_stat_init.c
+++ b/lib/zip_stat_init.c
@@ -1,6 +1,6 @@
 /*
   zip_stat_init.c -- initialize struct zip_stat.
-  Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner
+  Copyright (C) 2006-2009 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>
@@ -40,12 +40,13 @@
 ZIP_EXTERN void
 zip_stat_init(struct zip_stat *st)
 {
+    st->valid = 0;
     st->name = NULL;
-    st->index = -1;
+    st->index = ZIP_UINT64_MAX;
     st->crc = 0;
     st->mtime = (time_t)-1;
-    st->size = -1;
-    st->comp_size = -1;
+    st->size = 0;
+    st->comp_size = 0;
     st->comp_method = ZIP_CM_STORE;
     st->encryption_method = ZIP_EM_NONE;
 }
diff --git a/lib/zip_unchange.c b/lib/zip_unchange.c
index ed0d4de..58ec54b 100644
--- a/lib/zip_unchange.c
+++ b/lib/zip_unchange.c
@@ -40,7 +40,7 @@
 
 
 ZIP_EXTERN int
-zip_unchange(struct zip *za, int idx)
+zip_unchange(struct zip *za, zip_uint64_t idx)
 {
     return _zip_unchange(za, idx, 0);
 }
@@ -48,11 +48,11 @@
 
 
 int
-_zip_unchange(struct zip *za, int idx, int allow_duplicates)
+_zip_unchange(struct zip *za, zip_uint64_t idx, int allow_duplicates)
 {
     int i;
     
-    if (idx < 0 || idx >= za->nentry) {
+    if (idx >= za->nentry) {
 	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
 	return -1;
     }
diff --git a/lib/zip_unchange_data.c b/lib/zip_unchange_data.c
index 6fe89f4..431f2d0 100644
--- a/lib/zip_unchange_data.c
+++ b/lib/zip_unchange_data.c
@@ -1,6 +1,4 @@
 /*
-  $NiH: zip_unchange_data.c,v 1.14 2004/11/30 23:02:47 wiz Exp $
-
   zip_unchange_data.c -- undo helper function
   Copyright (C) 1999, 2004 Dieter Baron and Thomas Klausner
 
@@ -43,8 +41,7 @@
 _zip_unchange_data(struct zip_entry *ze)
 {
     if (ze->source) {
-	(void)ze->source->f(ze->source->ud, NULL, 0, ZIP_SOURCE_FREE);
-	free(ze->source);
+	zip_source_free(ze->source);
 	ze->source = NULL;
     }
     
diff --git a/lib/zipint.h b/lib/zipint.h
index f5a81b1..3f90668 100644
--- a/lib/zipint.h
+++ b/lib/zipint.h
@@ -3,7 +3,7 @@
 
 /*
   zipint.h -- internal declarations.
-  Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2009 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>
@@ -88,11 +88,9 @@
 enum zip_state { ZIP_ST_UNCHANGED, ZIP_ST_DELETED, ZIP_ST_REPLACED,
 		 ZIP_ST_ADDED, ZIP_ST_RENAMED };
 
-/* constants for struct zip_file's member flags */
+/* error source for layered sources */
 
-#define ZIP_ZF_EOF	1 /* EOF reached */
-#define ZIP_ZF_DECOMP	2 /* decompress data */
-#define ZIP_ZF_CRC	4 /* compute and compare CRC */
+enum zip_les { ZIP_LES_NONE, ZIP_LES_UPPER, ZIP_LES_LOWER, ZIP_LES_INVAL };
 
 /* directory entry: general purpose bit flags */
 
@@ -118,12 +116,14 @@
     unsigned int flags;		/* archive global flags */
     unsigned int ch_flags;	/* changed archive global flags */
 
+    char *default_password;	/* password used when no other supplied */
+
     struct zip_cdir *cdir;	/* central directory */
     char *ch_comment;		/* changed archive comment */
     int ch_comment_len;		/* length of changed zip archive
 				 * comment, -1 if unchanged */
-    int nentry;			/* number of entries */
-    int nentry_alloc;		/* number of entries allocated */
+    zip_uint64_t nentry;	/* number of entries */
+    zip_uint64_t nentry_alloc;	/* number of entries allocated */
     struct zip_entry *entry;	/* entries */
     int nfile;			/* number of opened files within archive */
     int nfile_alloc;		/* number of files allocated */
@@ -135,18 +135,8 @@
 struct zip_file {
     struct zip *za;		/* zip archive containing this file */
     struct zip_error error;	/* error information */
-    int flags;			/* -1: eof, >0: error */
-
-    int method;			/* compression method */
-    off_t fpos;			/* position within zip file (fread/fwrite) */
-    unsigned long bytes_left;	/* number of bytes left to read */
-    unsigned long cbytes_left;  /* number of bytes of compressed data left */
-    
-    unsigned long crc;		/* CRC so far */
-    unsigned long crc_orig;	/* CRC recorded in archive */
-    
-    char *buffer;
-    z_stream *zstr;
+    int eof;
+    struct zip_source *src;	/* data source */
 };
 
 /* zip archive directory entry (central or local) */
@@ -187,8 +177,14 @@
 
 
 struct zip_source {
-    zip_source_callback f;
+    struct zip_source *src;
+    union {
+	zip_source_callback f;
+	zip_source_layered_callback l;
+    } cb;
     void *ud;
+    enum zip_les error_source;
+    int is_open;
 };
 
 /* entry in zip archive directory */
@@ -213,6 +209,8 @@
 			((x)->state == ZIP_ST_REPLACED  \
 			 || (x)->state == ZIP_ST_ADDED)
 
+#define ZIP_IS_RDONLY(za)	((za)->ch_flags & ZIP_AFL_RDONLY)
+
 
 
 int _zip_cdir_compute_crc(struct zip *, uLong *);
@@ -224,7 +222,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 *);
+		     zip_uint32_t *, int, struct zip_error *);
 void _zip_dirent_torrent_normalize(struct zip_dirent *);
 int _zip_dirent_write(struct zip_dirent *, FILE *, int, struct zip_error *);
 
@@ -238,6 +236,7 @@
 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);
+void _zip_error_set_from_source(struct zip_error *, struct zip_source *);
 const char *_zip_error_strerror(struct zip_error *);
 
 int _zip_file_fillbuf(void *, size_t, struct zip_file *);
@@ -245,20 +244,27 @@
 
 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);
+struct zip *_zip_open(const char *, FILE *, int, int, int *);
 
+struct zip_source *_zip_source_file_or_p(struct zip *, const char *, FILE *,
+					 zip_uint64_t, zip_int64_t, int,
+					 const struct zip_stat *);
+struct zip_source *_zip_source_new(struct zip *);
+
+int _zip_changed(struct zip *, int *);
 void _zip_free(struct zip *);
-const char *_zip_get_name(struct zip *, int, int, struct zip_error *);
+const char *_zip_get_name(struct zip *, zip_uint64_t, int, struct zip_error *);
 int _zip_local_header_read(struct zip *, int);
 void *_zip_memdup(const void *, size_t, struct zip_error *);
 int _zip_name_locate(struct zip *, const char *, int, struct zip_error *);
 struct zip *_zip_new(struct zip_error *);
 unsigned short _zip_read2(unsigned char **);
 unsigned int _zip_read4(unsigned char **);
-int _zip_replace(struct zip *, int, const char *, struct zip_source *);
-int _zip_set_name(struct zip *, int, const char *);
-int _zip_unchange(struct zip *, int, int);
+zip_int64_t _zip_replace(struct zip *, zip_uint64_t, const char *,
+			 struct zip_source *);
+int _zip_set_name(struct zip *, zip_uint64_t, const char *);
+void _zip_u2d_time(time_t, unsigned short *, unsigned short *);
+int _zip_unchange(struct zip *, zip_uint64_t, int);
 void _zip_unchange_data(struct zip_entry *);
 
 #endif /* zipint.h */
diff --git a/libzip.pc.in b/libzip.pc.in
index ad1e565..f1301be 100644
--- a/libzip.pc.in
+++ b/libzip.pc.in
@@ -2,6 +2,7 @@
 exec_prefix=@exec_prefix@
 libdir=@libdir@
 includedir=@includedir@
+libincludedir=@libdir@/libzip/include
 
 zipcmp=@prefix@/bin/zipcmp
 
@@ -9,5 +10,5 @@
 Description: library for handling zip archives
 Version: @VERSION@
 Libs: -L${libdir} -lzip @LIBS@
-Cflags: -I${includedir}
+Cflags: -I${includedir} -I${libincludedir}
 
diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt
index 8de246d..e0bc4db 100644
--- a/man/CMakeLists.txt
+++ b/man/CMakeLists.txt
@@ -10,10 +10,12 @@
   zip_error_to_str.mdoc
   zip_errors.mdoc
   zip_fclose.mdoc
+  zip_fdopen.mdoc
   zip_file_strerror.mdoc
   zip_fopen.mdoc
   zip_fread.mdoc
   zip_get_archive_comment.mdoc
+  zip_get_archive_flag.mdoc
   zip_get_file_comment.mdoc
   zip_get_name.mdoc
   zip_get_num_files.mdoc
@@ -21,6 +23,7 @@
   zip_open.mdoc
   zip_rename.mdoc
   zip_set_archive_comment.mdoc
+  zip_set_archive_flag.mdoc
   zip_set_file_comment.mdoc
   zip_source_buffer.mdoc
   zip_source_file.mdoc
@@ -37,6 +40,7 @@
 SET(MDOC1_PAGES
   zipcmp.mdoc
   zipmerge.mdoc
+  ziptorrent.mdoc
 )
 SET(MDOC_PAGES ${MDOC1_PAGES} ${MDOC3_PAGES})
 STRING(REGEX REPLACE .mdoc "" MAN1_PAGES "${MDOC1_PAGES}")
@@ -61,31 +65,44 @@
   INSTALL(FILES ${MAN_PAGE}.${MANFMT} DESTINATION ${MAN_PATH}/man3
     RENAME ${MAN_PAGE}.3)
 ENDFOREACH(MAN_PAGE ${PROGRAMS})
+# XXX: usually symlinks, but I only know how to do this way
+INSTALL(FILES zip_error_clear.${MANFMT} DESTINATION ${MAN_PATH}/man3
+  RENAME zip_file_error_clear.3)
+INSTALL(FILES zip_error_get.${MANFMT} DESTINATION ${MAN_PATH}/man3
+  RENAME zip_file_error_get.3)
+INSTALL(FILES zip_fopen.${MANFMT} DESTINATION ${MAN_PATH}/man3
+  RENAME zip_fopen_index.3)
+INSTALL(FILES zip_add.${MANFMT} DESTINATION ${MAN_PATH}/man3
+  RENAME zip_replace.3)
+INSTALL(FILES zip_stat.${MANFMT} DESTINATION ${MAN_PATH}/man3
+  RENAME zip_stat_index.3)
+INSTALL(FILES zip_file_strerror.${MANFMT} DESTINATION ${MAN_PATH}/man3
+  RENAME zip_strerror.3)
 
-# custom targets
+# custom maintainer targets
 
-FOREACH(MAN ${MAN_PAGES})
-  ADD_CUSTOM_TARGET(${MAN}.man
-    DEPENDS ${MAN}.mdoc
-    COMMAND mdoc2man ${CMAKE_CURRENT_SOURCE_DIR}/${MAN}.mdoc > ${MAN}.new
-    COMMAND diff -I NiH ${MAN}.new ${CMAKE_CURRENT_SOURCE_DIR}/${MAN}.man || mv ${MAN}.new ${CMAKE_CURRENT_SOURCE_DIR}/${MAN}.man
-    COMMAND rm -f ${MAN}.new
-    COMMENT Updating man page ${MAN}.man
-    )
-  ADD_CUSTOM_TARGET(${MAN}.html
-    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${MAN}.mdoc
-    COMMAND nroff -mdoc2html ${CMAKE_CURRENT_SOURCE_DIR}/${MAN}.mdoc | sed -e "s,../html[0-9]/,," > ${MAN}.html
-    COMMENT Updating HTML page ${MAN}.html
-    )
-ENDFOREACH(MAN)
+#FOREACH(MAN ${MAN_PAGES})
+#  ADD_CUSTOM_TARGET(${MAN}.man
+#    DEPENDS ${MAN}.mdoc
+#    COMMAND mdoc2man ${CMAKE_CURRENT_SOURCE_DIR}/${MAN}.mdoc > ${MAN}.new
+#    COMMAND diff -I NiH ${MAN}.new ${CMAKE_CURRENT_SOURCE_DIR}/${MAN}.man || mv ${MAN}.new ${CMAKE_CURRENT_SOURCE_DIR}/${MAN}.man
+#    COMMAND rm -f ${MAN}.new
+#    COMMENT Updating man page ${MAN}.man
+#    )
+#  ADD_CUSTOM_TARGET(${MAN}.html
+#    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${MAN}.mdoc
+#    COMMAND nroff -mdoc2html ${CMAKE_CURRENT_SOURCE_DIR}/${MAN}.mdoc | sed -e "s,../html[0-9]/,," > ${MAN}.html
+#    COMMENT Updating HTML page ${MAN}.html
+#    )
+#ENDFOREACH(MAN)
 
-STRING(REGEX REPLACE .mdoc .man MANDEPEND "${MDOC_PAGES}")
-ADD_CUSTOM_TARGET(update-man
-  DEPENDS ${MANDEPEND})
+#STRING(REGEX REPLACE .mdoc .man MANDEPEND "${MDOC_PAGES}")
+#ADD_CUSTOM_TARGET(update-man
+#  DEPENDS ${MANDEPEND})
 
-STRING(REGEX REPLACE .mdoc .html HTMLDEPEND "${MDOC_PAGES}")
-ADD_CUSTOM_TARGET(update-html
-  DEPENDS ${HTMLDEPEND})
+#STRING(REGEX REPLACE .mdoc .html HTMLDEPEND "${MDOC_PAGES}")
+#ADD_CUSTOM_TARGET(update-html
+#  DEPENDS ${HTMLDEPEND})
 
 # XXX: strange error:
 #[ 94%] zipcmp.html
diff --git a/man/Makefile.am b/man/Makefile.am
index 697a7c3..6229191 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -17,6 +17,7 @@
 	zip_error_to_str.mdoc \
 	zip_errors.mdoc \
 	zip_fclose.mdoc \
+	zip_fdopen.mdoc \
 	zip_file_strerror.mdoc \
 	zip_fopen.mdoc \
 	zip_fread.mdoc \
diff --git a/man/libzip.man b/man/libzip.man
index d3df817..113553c 100644
--- a/man/libzip.man
+++ b/man/libzip.man
@@ -1,6 +1,4 @@
 .\" Converted with mdoc2man 0.2
-.\" from NiH: libzip.mdoc,v 1.7 2006/04/23 12:50:32 wiz Exp 
-.\" $NiH: libzip.mdoc,v 1.7 2006/04/23 12:50:32 wiz Exp $
 .\"
 .\" libzip.mdoc \-- general overview of available functions
 .\" Copyright (C) 2005, 2006 Dieter Baron and Thomas Klausner
diff --git a/man/libzip.mdoc b/man/libzip.mdoc
index 97e7b6f..d95b1b8 100644
--- a/man/libzip.mdoc
+++ b/man/libzip.mdoc
@@ -1,7 +1,5 @@
-.\" $NiH: libzip.mdoc,v 1.7 2006/04/23 12:50:32 wiz Exp $
-.\"
 .\" libzip.mdoc -- general overview of available functions
-.\" Copyright (C) 2005, 2006 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2005-2009 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>
@@ -31,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd June 11, 2008
+.Dd February 15, 2009
 .Dt LIBZIP 3
 .Os
 .Sh NAME
@@ -50,6 +48,7 @@
 .Sh READING ZIP ARCHIVES
 .Ss open archive
 .Xr zip_open 3
+.Xr zip_fdopen 3
 .Ss find files
 .Xr zip_name_locate 3
 .Ss read files
diff --git a/man/make_zip_errors.sh b/man/make_zip_errors.sh
index 21b5296..1113828 100644
--- a/man/make_zip_errors.sh
+++ b/man/make_zip_errors.sh
@@ -1,7 +1,5 @@
 #!/bin/sh
 
-#  $NiH: make_zip_errors.sh,v 1.3 2005/01/20 21:03:36 dillo Exp $
-#
 #  make_zip_errrors.sh: create zip_errors.mdoc from zip.h
 #  Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner
 #
@@ -47,13 +45,9 @@
     exit 1
 fi
 
-rcsid=`echo '$NiH: make_zip_errors.sh,v 1.3 2005/01/20 21:03:36 dillo Exp $' | tr -d '$'`
-inrcsid=`sed -n 's/^  \$\([^$]*[^ ]\) *\$$/\1/p' "$1"`
 date=`date '+%B %e, %Y' | sed 's/  / /'`
 
 cat <<EOF >> "$2.$$" || exit 1
-.\" \$NiH\$
-.\"
 .\" zip_errors.mdoc -- list of all libzip error codes
 .\" Copyright (C) 2004, 2005 Dieter Baron and Thomas Klausner
 .\"
@@ -87,8 +81,6 @@
 .\"
 .\"   This file was generated automatically by $0
 .\"   from $1; make changes there.
-.\"	$rcsid
-.\"	$inrcsid
 .\"
 .Dd $date
 .Dt ZIP_ERRORS 3
diff --git a/man/zip_add.man b/man/zip_add.man
index 1ede21c..b7935e4 100644
--- a/man/zip_add.man
+++ b/man/zip_add.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_add.mdoc,v 1.9 2005/06/09 21:14:54 wiz Exp 
-.\" $NiH: zip_add.mdoc,v 1.9 2005/06/09 21:14:54 wiz Exp $
-.\"
 .\" zip_add.mdoc \-- add files to zip archive
 .\" Copyright (C) 2004, 2005, 2006 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_add.mdoc b/man/zip_add.mdoc
index 114d995..bc5c204 100644
--- a/man/zip_add.mdoc
+++ b/man/zip_add.mdoc
@@ -1,7 +1,5 @@
-.\" $NiH: zip_add.mdoc,v 1.9 2005/06/09 21:14:54 wiz Exp $
-.\"
 .\" zip_add.mdoc -- add files to zip archive
-.\" Copyright (C) 2004, 2005, 2006 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2004-2009 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>
@@ -31,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd April 9, 2006
+.Dd March 10, 2009
 .Dt ZIP_ADD 3
 .Os
 .Sh NAME
@@ -42,11 +40,11 @@
 libzip (-lzip)
 .Sh SYNOPSIS
 .In zip.h
-.Ft int
+.Ft zip_int64_t
 .Fn zip_add "struct zip *archive" "const char *name" \
 "struct zip_source *source"
 .Ft int
-.Fn zip_replace "struct zip *archive" "int index" \
+.Fn zip_replace "struct zip *archive" "zip_uint64_t index" \
 "struct zip_source *source"
 .Sh DESCRIPTION
 The function
@@ -72,8 +70,11 @@
 functions cited in
 .Sx SEE ALSO .
 .Sh RETURN VALUES
-Upon successful completion, the index of the new file in the archive
-is returned.
+Upon successful completion,
+.Fn zip_add
+returns the index of the new file in the archive, and
+.Fn zip_replace
+returns 0.
 Otherwise, \-1 is returned and the error code in
 .Ar archive
 is set to indicate the error.
diff --git a/man/zip_add_dir.man b/man/zip_add_dir.man
index 5472cc0..04d334a 100644
--- a/man/zip_add_dir.man
+++ b/man/zip_add_dir.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_add_dir.mdoc,v 1.1 2006/10/03 18:55:51 wiz Exp 
-.\" $NiH: zip_add_dir.mdoc,v 1.1 2006/10/03 18:55:51 wiz Exp $
-.\"
 .\" zip_add_dir.mdoc \-- add directory to zip archive
 .\" Copyright (C) 2006 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_add_dir.mdoc b/man/zip_add_dir.mdoc
index 9a1cbc5..7f7014e 100644
--- a/man/zip_add_dir.mdoc
+++ b/man/zip_add_dir.mdoc
@@ -1,7 +1,5 @@
-.\" $NiH: zip_add_dir.mdoc,v 1.1 2006/10/03 18:55:51 wiz Exp $
-.\"
 .\" zip_add_dir.mdoc -- add directory to zip archive
-.\" Copyright (C) 2006 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2006-2009 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>
@@ -31,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd October 3, 2006
+.Dd March 10, 2009
 .Dt ZIP_ADD_DIR 3
 .Os
 .Sh NAME
@@ -41,7 +39,7 @@
 libzip (-lzip)
 .Sh SYNOPSIS
 .In zip.h
-.Ft int
+.Ft zip_int64_t
 .Fn zip_add_dir "struct zip *archive" "const char *name"
 .Sh DESCRIPTION
 The function
diff --git a/man/zip_close.man b/man/zip_close.man
index 49aeaa0..a94e321 100644
--- a/man/zip_close.man
+++ b/man/zip_close.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_close.mdoc,v 1.13 2005/06/09 21:13:12 wiz Exp 
-.\" $NiH: zip_close.mdoc,v 1.13 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_close.mdoc \-- close zip archive
 .\" Copyright (C) 2003, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_close.mdoc b/man/zip_close.mdoc
index 876280f..0db9bb6 100644
--- a/man/zip_close.mdoc
+++ b/man/zip_close.mdoc
@@ -1,7 +1,5 @@
-.\" $NiH: zip_close.mdoc,v 1.13 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_close.mdoc -- close zip archive
-.\" Copyright (C) 2003, 2005 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2003-2009 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>
@@ -31,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd July 24, 2008
+.Dd February 15, 2009
 .Dt ZIP_CLOSE 3
 .Os
 .Sh NAME
@@ -102,6 +100,7 @@
 .Sh SEE ALSO
 .Xr libzip 3 ,
 .Xr zip_error_get 3 ,
+.Xr zip_fdopen 3 ,
 .Xr zip_open 3 ,
 .Xr zip_strerror 3
 .Sh AUTHORS
diff --git a/man/zip_delete.man b/man/zip_delete.man
index 6689e72..7023e01 100644
--- a/man/zip_delete.man
+++ b/man/zip_delete.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_delete.mdoc,v 1.10 2005/06/09 21:13:12 wiz Exp 
-.\" $NiH: zip_delete.mdoc,v 1.10 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_delete.mdoc \-- delete files from zip archive
 .\" Copyright (C) 2003, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_delete.mdoc b/man/zip_delete.mdoc
index 8c7b7a2..d17eadc 100644
--- a/man/zip_delete.mdoc
+++ b/man/zip_delete.mdoc
@@ -1,7 +1,5 @@
-.\" $NiH: zip_delete.mdoc,v 1.10 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_delete.mdoc -- delete files from zip archive
-.\" Copyright (C) 2003, 2005 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2003-2009 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>
@@ -31,7 +29,7 @@
 .\" 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
+.Dd March 10, 2009
 .Dt ZIP_DELETE 3
 .Os
 .Sh NAME
@@ -42,7 +40,7 @@
 .Sh SYNOPSIS
 .In zip.h
 .Ft int
-.Fn zip_delete "struct zip *archive" "int index"
+.Fn zip_delete "struct zip *archive" "zip_uint64_t index"
 .Sh DESCRIPTION
 The file at position
 .Ar index
diff --git a/man/zip_error_clear.man b/man/zip_error_clear.man
index 4435a6a..750f832 100644
--- a/man/zip_error_clear.man
+++ b/man/zip_error_clear.man
@@ -1,5 +1,3 @@
-.\" $NiH$
-.\"
 .\" zip_clear_error.mdoc \-- clear error state for archive or file
 .\" Copyright (C) 2006 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_error_clear.mdoc b/man/zip_error_clear.mdoc
index c800bd4..5268723 100644
--- a/man/zip_error_clear.mdoc
+++ b/man/zip_error_clear.mdoc
@@ -1,5 +1,3 @@
-.\" $NiH$
-.\"
 .\" zip_clear_error.mdoc -- clear error state for archive or file
 .\" Copyright (C) 2006 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_error_get.man b/man/zip_error_get.man
index e5b988b..ce3d547 100644
--- a/man/zip_error_get.man
+++ b/man/zip_error_get.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_error_get.mdoc,v 1.9 2006/04/23 12:45:10 wiz Exp 
-.\" $NiH: zip_error_get.mdoc,v 1.9 2006/04/23 12:45:10 wiz Exp $
-.\"
 .\" zip_error_get.mdoc \-- get error codes for archive or file
 .\" Copyright (C) 2004, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_error_get.mdoc b/man/zip_error_get.mdoc
index 861e6db..4fdf20a 100644
--- a/man/zip_error_get.mdoc
+++ b/man/zip_error_get.mdoc
@@ -1,5 +1,3 @@
-.\" $NiH: zip_error_get.mdoc,v 1.9 2006/04/23 12:45:10 wiz Exp $
-.\"
 .\" zip_error_get.mdoc -- get error codes for archive or file
 .\" Copyright (C) 2004, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_error_get_sys_type.man b/man/zip_error_get_sys_type.man
index c86e380..9e13948 100644
--- a/man/zip_error_get_sys_type.man
+++ b/man/zip_error_get_sys_type.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_error_get_sys_type.mdoc,v 1.4 2005/06/09 21:13:12 wiz Exp 
-.\" $NiH: zip_error_get_sys_type.mdoc,v 1.4 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_error_get_sys_type.mdoc \-- get type of error
 .\" Copyright (C) 2004, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_error_get_sys_type.mdoc b/man/zip_error_get_sys_type.mdoc
index 142d296..dedab2c 100644
--- a/man/zip_error_get_sys_type.mdoc
+++ b/man/zip_error_get_sys_type.mdoc
@@ -1,5 +1,3 @@
-.\" $NiH: zip_error_get_sys_type.mdoc,v 1.4 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_error_get_sys_type.mdoc -- get type of error
 .\" Copyright (C) 2004, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_error_to_str.man b/man/zip_error_to_str.man
index 3563b4a..9f82d27 100644
--- a/man/zip_error_to_str.man
+++ b/man/zip_error_to_str.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_error_to_str.mdoc,v 1.7 2005/06/09 21:13:12 wiz Exp 
-.\" $NiH: zip_error_to_str.mdoc,v 1.7 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_error_to_str.mdoc \-- get string representation of zip error code
 .\" Copyright (C) 2003, 2004, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_error_to_str.mdoc b/man/zip_error_to_str.mdoc
index 2851d9f..870029d 100644
--- a/man/zip_error_to_str.mdoc
+++ b/man/zip_error_to_str.mdoc
@@ -1,7 +1,5 @@
-.\" $NiH: zip_error_to_str.mdoc,v 1.7 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_error_to_str.mdoc -- get string representation of zip error code
-.\" Copyright (C) 2003, 2004, 2005 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2003-2009 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>
@@ -31,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd November 24, 2004
+.Dd March 10, 2009
 .Dt ZIP_ERROR_TO_STR 3
 .Os
 .Sh NAME
@@ -42,7 +40,7 @@
 .Sh SYNOPSIS
 .In zip.h
 .Ft int
-.Fn zip_error_to_str "char *buf" "int len" "int ze" "int se"
+.Fn zip_error_to_str "char *buf" "zip_uint64_t len" "int ze" "int se"
 .Sh DESCRIPTION
 The
 .Fn zip_error_to_str
diff --git a/man/zip_errors.man b/man/zip_errors.man
index 0012a52..46093e4 100644
--- a/man/zip_errors.man
+++ b/man/zip_errors.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_errors.mdoc,v 1.5 2005/06/09 21:13:12 wiz Exp 
-.\" $NiH: zip_errors.mdoc,v 1.5 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_errors.mdoc \-- list of all libzip error codes
 .\" Copyright (C) 2004, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_errors.mdoc b/man/zip_errors.mdoc
index 02add36..9aa4cc9 100644
--- a/man/zip_errors.mdoc
+++ b/man/zip_errors.mdoc
@@ -1,5 +1,3 @@
-.\" $NiH: zip_errors.mdoc,v 1.5 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_errors.mdoc -- list of all libzip error codes
 .\" Copyright (C) 2004, 2005 Dieter Baron and Thomas Klausner
 .\"
@@ -33,10 +31,8 @@
 .\"
 .\"   This file was generated automatically by ./make_zip_errors.sh
 .\"   from ./../lib/zip.h; make changes there.
-.\"	NiH: make_zip_errors.sh,v 1.3 2005/01/20 21:03:36 dillo Exp 
-.\"	NiH: zip.h,v 1.48 2005/01/20 21:00:29 dillo Exp
 .\"
-.Dd January 20, 2005
+.Dd March 10, 2009
 .Dt ZIP_ERRORS 3
 .Os
 .Sh NAME
@@ -97,6 +93,14 @@
 Can't remove file.
 .It Bq Er ZIP_ER_DELETED
 Entry has been deleted.
+.It Bq Er ZIP_ER_ENCRNOTSUPP
+Encryption method not supported.
+.It Bq Er ZIP_ER_RDONLY
+Read-only archive. 
+.It Bq Er ZIP_ER_NOPASSWD
+No password provided.
+.It Bq Er ZIP_ER_WRONGPASSWD
+Wrong password provided.
 .El
 .Sh AUTHORS
 .An -nosplit
diff --git a/man/zip_fclose.man b/man/zip_fclose.man
index 102456f..a644c8f 100644
--- a/man/zip_fclose.man
+++ b/man/zip_fclose.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_fclose.mdoc,v 1.8 2005/06/09 21:13:12 wiz Exp 
-.\" $NiH: zip_fclose.mdoc,v 1.8 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_fclose.mdoc \-- close file in zip archive
 .\" Copyright (C) 2003, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_fclose.mdoc b/man/zip_fclose.mdoc
index f487877..e709e8f 100644
--- a/man/zip_fclose.mdoc
+++ b/man/zip_fclose.mdoc
@@ -1,5 +1,3 @@
-.\" $NiH: zip_fclose.mdoc,v 1.8 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_fclose.mdoc -- close file in zip archive
 .\" Copyright (C) 2003, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_fdopen.man b/man/zip_fdopen.man
new file mode 100644
index 0000000..865db39
--- /dev/null
+++ b/man/zip_fdopen.man
@@ -0,0 +1,151 @@
+.\" zip_fdopen.mdoc \-- open zip archive using existing file descriptor
+.\" Copyright (C) 2009 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.
+.\"
+.TH ZIP_FDOPEN 3 "February 15, 2009" NiH
+.SH "NAME"
+zip_fdopen \- open zip archive using open file descriptor
+.SH "LIBRARY"
+libzip (-lzip)
+.SH "SYNOPSIS"
+#include <zip.h>
+.PP
+struct zip *
+zip_fdopen(int fd, int flags, int *errorp);
+.SH "DESCRIPTION"
+The zip archive specified by the open file descriptor
+\fBfd\fR
+is opened and a pointer to a
+.PP
+struct zip,
+used to manipulate the archive, is returned.
+In contrast to
+zip_open(3),
+using
+.Nm zip_fdopen
+the archive can only be opened in read-only mode.
+The
+\fBfd\fR
+argument may not be used any longer after calling
+.Nm zip_fdopen.
+The
+.Fa flags
+are specified by
+.I or'ing
+the following values, or 0 for none of them.
+.RS
+.TP 15
+\fBZIP_CHECKCONS\fR
+Perform additional consistency checks on the archive, and error if
+they fail.
+.RE
+.PP
+If an error occurs and
+\fBerrorp\fR
+is
+.No non-\fBNULL,\fR
+it will be set to the corresponding error code.
+.SH "RETURN VALUES"
+Upon successful completion
+zip_fdopen
+returns a
+.PP
+struct zip
+pointer, and
+\fBfd\fR
+should not be used any longer.
+Otherwise,
+\fBNULL\fR
+is returned and
+\fB*errorp\fR
+is set to indicate the error.
+In the error case,
+\fBfd\fR
+remains unchanged.
+.SH "ERRORS"
+The file specified by
+\fBfd\fR
+is prepared for use by
+libzip(3)
+unless:
+.RS
+.TP 4
+[ZIP_ER_INCONS]
+Inconsistencies were found in the file specified by
+\fBpath\fR
+and
+\fBZIP_CHECKCONS\fR
+was specified.
+.TP 4
+[ZIP_ER_INVAL]
+The
+\fBflags\fR
+argument is invalid.
+Not all
+zip_open(3)
+flags are allowed for
+.Nm zip_fdopen,
+see
+DESCRIPTION.
+.TP 4
+[ZIP_ER_MEMORY]
+Required memory could not be allocated.
+.TP 4
+[ZIP_ER_NOZIP]
+The file specified by
+\fBfd\fR
+is not a zip archive.
+.TP 4
+[ZIP_ER_OPEN]
+The file specified by
+\fBfd\fR
+could not be prepared for use by
+libzip(3).
+.TP 4
+[ZIP_ER_READ]
+A read error occurred; see
+.Va errno
+for details.
+.TP 4
+[ZIP_ER_SEEK]
+The file specified by
+\fBfd\fR
+does not allow seeks.
+.RE
+.SH "SEE ALSO"
+libzip(3),
+zip_close(3),
+zip_error_to_str(3),
+zip_open(3)
+.SH "AUTHORS"
+
+Dieter Baron <dillo@giga.or.at>
+and
+Thomas Klausner <tk@giga.or.at>
diff --git a/man/zip_fdopen.mdoc b/man/zip_fdopen.mdoc
new file mode 100644
index 0000000..78194d9
--- /dev/null
+++ b/man/zip_fdopen.mdoc
@@ -0,0 +1,143 @@
+.\" zip_fdopen.mdoc -- open zip archive using existing file descriptor
+.\" Copyright (C) 2009 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.
+.\"
+.Dd February 15, 2009
+.Dt ZIP_FDOPEN 3
+.Os
+.Sh NAME
+.Nm zip_fdopen
+.Nd open zip archive using open file descriptor
+.Sh LIBRARY
+libzip (-lzip)
+.Sh SYNOPSIS
+.In zip.h
+.Ft struct zip *
+.Fn zip_fdopen "int fd" "int flags" "int *errorp"
+.Sh DESCRIPTION
+The zip archive specified by the open file descriptor
+.Ar fd
+is opened and a pointer to a
+.Ft struct zip ,
+used to manipulate the archive, is returned.
+In contrast to
+.Xr zip_open 3 ,
+using
+.Nm zip_fdopen
+the archive can only be opened in read-only mode.
+The
+.Ar fd
+argument may not be used any longer after calling
+.Nm zip_fdopen .
+The
+.Fa flags
+are specified by
+.Em or Ns No 'ing
+the following values, or 0 for none of them.
+.Bl -tag -offset indent -width ZIP_CHECKCONS
+.It Dv ZIP_CHECKCONS
+Perform additional consistency checks on the archive, and error if
+they fail.
+.El
+.Pp
+If an error occurs and
+.Ar errorp
+is
+.No non- Ns Dv NULL ,
+it will be set to the corresponding error code.
+.Sh RETURN VALUES
+Upon successful completion
+.Fn zip_fdopen
+returns a
+.Ft struct zip
+pointer, and
+.Ar fd
+should not be used any longer.
+Otherwise,
+.Dv NULL
+is returned and
+.Ar *errorp
+is set to indicate the error.
+In the error case,
+.Ar fd
+remains unchanged.
+.Sh ERRORS
+The file specified by
+.Ar fd
+is prepared for use by
+.Xr libzip 3
+unless:
+.Bl -tag -width Er
+.It Bq Er ZIP_ER_INCONS
+Inconsistencies were found in the file specified by
+.Ar path
+and
+.Dv ZIP_CHECKCONS
+was specified.
+.It Bq Er ZIP_ER_INVAL
+The
+.Ar flags
+argument is invalid.
+Not all
+.Xr zip_open 3
+flags are allowed for
+.Nm zip_fdopen ,
+see
+.Sx DESCRIPTION .
+.It Bq Er ZIP_ER_MEMORY
+Required memory could not be allocated.
+.It Bq Er ZIP_ER_NOZIP
+The file specified by
+.Ar fd
+is not a zip archive.
+.It Bq Er ZIP_ER_OPEN
+The file specified by
+.Ar fd
+could not be prepared for use by
+.Xr libzip 3 .
+.It Bq Er ZIP_ER_READ
+A read error occurred; see
+.Va errno
+for details.
+.It Bq Er ZIP_ER_SEEK
+The file specified by
+.Ar fd
+does not allow seeks.
+.El
+.Sh SEE ALSO
+.Xr libzip 3 ,
+.Xr zip_close 3 ,
+.Xr zip_error_to_str 3 ,
+.Xr zip_open 3
+.Sh AUTHORS
+.An -nosplit
+.An Dieter Baron Aq dillo@giga.or.at
+and
+.An Thomas Klausner Aq tk@giga.or.at
diff --git a/man/zip_file_strerror.man b/man/zip_file_strerror.man
index 31d6633..eeadc8c 100644
--- a/man/zip_file_strerror.man
+++ b/man/zip_file_strerror.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_file_strerror.mdoc,v 1.6 2005/06/09 21:13:12 wiz Exp 
-.\" $NiH: zip_file_strerror.mdoc,v 1.6 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_file_strerror.mdoc \-- get string representation for a zip error
 .\" Copyright (C) 2003, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_file_strerror.mdoc b/man/zip_file_strerror.mdoc
index 5875277..81f56d1 100644
--- a/man/zip_file_strerror.mdoc
+++ b/man/zip_file_strerror.mdoc
@@ -1,5 +1,3 @@
-.\" $NiH: zip_file_strerror.mdoc,v 1.6 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_file_strerror.mdoc -- get string representation for a zip error
 .\" Copyright (C) 2003, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_fopen.man b/man/zip_fopen.man
index 9392e78..a20556a 100644
--- a/man/zip_fopen.man
+++ b/man/zip_fopen.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_fopen.mdoc,v 1.13 2005/06/09 21:13:12 wiz Exp 
-.\" $NiH: zip_fopen.mdoc,v 1.13 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_fopen.mdoc \-- open file in zip archive for reading
 .\" Copyright (C) 2003, 2004, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_fopen.mdoc b/man/zip_fopen.mdoc
index 2237d19..0eb5776 100644
--- a/man/zip_fopen.mdoc
+++ b/man/zip_fopen.mdoc
@@ -1,7 +1,5 @@
-.\" $NiH: zip_fopen.mdoc,v 1.13 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_fopen.mdoc -- open file in zip archive for reading
-.\" Copyright (C) 2003, 2004, 2005 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2003-2009 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>
@@ -31,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd April 14, 2004
+.Dd March 10, 2009
 .Dt ZIP_FOPEN 3
 .Os
 .Sh NAME
@@ -45,7 +43,7 @@
 .Ft struct zip_file *
 .Fn zip_fopen "struct zip *archive" "const char *fname" "int flags"
 .Ft struct zip_file *
-.Fn zip_fopen_index "struct zip *archive" "int index" "int flags"
+.Fn zip_fopen_index "struct zip *archive" "zip_uint64_t index" "int flags"
 .Sh DESCRIPTION
 The
 .Fn zip_fopen
@@ -90,6 +88,8 @@
 The file data has been changed.
 .It Bq Er ZIP_ER_COMPNOTSUPP
 The compression method used is not supported.
+.It Bq Er ZIP_ER_ENCRNOTSUPP
+The encryption method used is not supported.
 .It Bq Er ZIP_ER_MEMORY
 Required memory could not be allocated.
 .It Bq Er ZIP_ER_READ
diff --git a/man/zip_fread.man b/man/zip_fread.man
index edae35b..9a03378 100644
--- a/man/zip_fread.man
+++ b/man/zip_fread.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_fread.mdoc,v 1.8 2005/06/09 21:13:12 wiz Exp 
-.\" $NiH: zip_fread.mdoc,v 1.8 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_fread.mdoc \-- read from file
 .\" Copyright (C) 2003, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_fread.mdoc b/man/zip_fread.mdoc
index 26f139c..694c143 100644
--- a/man/zip_fread.mdoc
+++ b/man/zip_fread.mdoc
@@ -1,7 +1,5 @@
-.\" $NiH: zip_fread.mdoc,v 1.8 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_fread.mdoc -- read from file
-.\" Copyright (C) 2003, 2005 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2003-2009 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>
@@ -31,7 +29,7 @@
 .\" 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
+.Dd March 10, 2009
 .Dt ZIP_FREAD 3
 .Os
 .Sh NAME
@@ -42,7 +40,7 @@
 .Sh SYNOPSIS
 .In zip.h
 .Ft int
-.Fn zip_fread "struct zip_file *file" "void *buf" "int nbytes"
+.Fn zip_fread "struct zip_file *file" "void *buf" "zip_uint64_t nbytes"
 .Sh DESCRIPTION
 The
 .Fn zip_fread
diff --git a/man/zip_get_archive_comment.man b/man/zip_get_archive_comment.man
index 08ad66c..e9bf825 100644
--- a/man/zip_get_archive_comment.man
+++ b/man/zip_get_archive_comment.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_get_archive_comment.mdoc,v 1.1 2006/04/09 19:05:48 wiz Exp 
-.\" $NiH: zip_get_archive_comment.mdoc,v 1.1 2006/04/09 19:05:48 wiz Exp $
-.\"
 .\" zip_get_archive_comment.mdoc \-- get zip archive comment
 .\" Copyright (C) 2006 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_get_archive_comment.mdoc b/man/zip_get_archive_comment.mdoc
index 01eb348..dee3317 100644
--- a/man/zip_get_archive_comment.mdoc
+++ b/man/zip_get_archive_comment.mdoc
@@ -1,5 +1,3 @@
-.\" $NiH: zip_get_archive_comment.mdoc,v 1.1 2006/04/09 19:05:48 wiz Exp $
-.\"
 .\" zip_get_archive_comment.mdoc -- get zip archive comment
 .\" Copyright (C) 2006 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_get_file_comment.man b/man/zip_get_file_comment.man
index dcc6a03..fb5fa12 100644
--- a/man/zip_get_file_comment.man
+++ b/man/zip_get_file_comment.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_get_file_comment.mdoc,v 1.3 2006/04/23 12:45:31 wiz Exp 
-.\" $NiH: zip_get_file_comment.mdoc,v 1.3 2006/04/23 12:45:31 wiz Exp $
-.\"
 .\" zip_get_file_comment.mdoc \-- get comment for file in zip
 .\" Copyright (C) 2006 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_get_file_comment.mdoc b/man/zip_get_file_comment.mdoc
index f3cde89..780db5f 100644
--- a/man/zip_get_file_comment.mdoc
+++ b/man/zip_get_file_comment.mdoc
@@ -1,7 +1,5 @@
-.\" $NiH: zip_get_file_comment.mdoc,v 1.3 2006/04/23 12:45:31 wiz Exp $
-.\"
 .\" zip_get_file_comment.mdoc -- get comment for file in zip
-.\" Copyright (C) 2006 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner
 .\"
 .\" This file is part of libzip, a library to manipulate ZIP files.
 .\" The authors can be contacted at <libzip@nih.at>
@@ -31,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd April 23, 2006
+.Dd March 10, 2009
 .Dt ZIP_GET_FILE_COMMENT 3
 .Os
 .Sh NAME
@@ -42,7 +40,7 @@
 .Sh SYNOPSIS
 .In zip.h
 .Ft const char *
-.Fn zip_get_file_comment "struct zip *archive" "int index" "int *lenp" "int flags"
+.Fn zip_get_file_comment "struct zip *archive" "zip_uint64_t index" "int *lenp" "int flags"
 .Sh DESCRIPTION
 The
 .Fn zip_get_file_comment
diff --git a/man/zip_get_name.man b/man/zip_get_name.man
index 78c609d..66b7340 100644
--- a/man/zip_get_name.man
+++ b/man/zip_get_name.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_get_name.mdoc,v 1.9 2005/06/09 21:13:12 wiz Exp 
-.\" $NiH: zip_get_name.mdoc,v 1.9 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_get_name.mdoc \-- get name of file by index
 .\" Copyright (C) 2003, 2004, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_get_name.mdoc b/man/zip_get_name.mdoc
index cfc22ce..743f117 100644
--- a/man/zip_get_name.mdoc
+++ b/man/zip_get_name.mdoc
@@ -1,5 +1,3 @@
-.\" $NiH: zip_get_name.mdoc,v 1.9 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_get_name.mdoc -- get name of file by index
 .\" Copyright (C) 2003, 2004, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_get_num_files.man b/man/zip_get_num_files.man
index f470c11..9958121 100644
--- a/man/zip_get_num_files.man
+++ b/man/zip_get_num_files.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_get_num_files.mdoc,v 1.4 2005/06/09 21:13:12 wiz Exp 
-.\" $NiH: zip_get_num_files.mdoc,v 1.4 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_get_num_files.mdoc \-- get number of files in archive
 .\" Copyright (C) 2003, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_get_num_files.mdoc b/man/zip_get_num_files.mdoc
index a341123..35c3cd9 100644
--- a/man/zip_get_num_files.mdoc
+++ b/man/zip_get_num_files.mdoc
@@ -1,5 +1,3 @@
-.\" $NiH: zip_get_num_files.mdoc,v 1.4 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_get_num_files.mdoc -- get number of files in archive
 .\" Copyright (C) 2003, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_name_locate.man b/man/zip_name_locate.man
index a60117c..e3702df 100644
--- a/man/zip_name_locate.man
+++ b/man/zip_name_locate.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_name_locate.mdoc,v 1.8 2005/06/09 21:14:54 wiz Exp 
-.\" $NiH: zip_name_locate.mdoc,v 1.8 2005/06/09 21:14:54 wiz Exp $
-.\"
 .\" zip_name_locate.mdoc \-- get index of file by name
 .\" Copyright (C) 2003, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_name_locate.mdoc b/man/zip_name_locate.mdoc
index 0134901..eeac3ed 100644
--- a/man/zip_name_locate.mdoc
+++ b/man/zip_name_locate.mdoc
@@ -1,5 +1,3 @@
-.\" $NiH: zip_name_locate.mdoc,v 1.8 2005/06/09 21:14:54 wiz Exp $
-.\"
 .\" zip_name_locate.mdoc -- get index of file by name
 .\" Copyright (C) 2003, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_open.man b/man/zip_open.man
index baa4c39..9af6886 100644
--- a/man/zip_open.man
+++ b/man/zip_open.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_open.mdoc,v 1.21 2005/06/09 21:13:12 wiz Exp 
-.\" $NiH: zip_open.mdoc,v 1.21 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_open.mdoc \-- open zip archive
 .\" Copyright (C) 2003, 2005 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_open.mdoc b/man/zip_open.mdoc
index 90d9982..1f1a556 100644
--- a/man/zip_open.mdoc
+++ b/man/zip_open.mdoc
@@ -1,7 +1,5 @@
-.\" $NiH: zip_open.mdoc,v 1.21 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_open.mdoc -- open zip archive
-.\" Copyright (C) 2003, 2005 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2003-2009 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>
@@ -31,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd December 27, 2003
+.Dd February 15, 2009
 .Dt ZIP_OPEN 3
 .Os
 .Sh NAME
@@ -128,7 +126,8 @@
 .Sh SEE ALSO
 .Xr libzip 3 ,
 .Xr zip_close 3 ,
-.Xr zip_error_to_str 3
+.Xr zip_error_to_str 3 ,
+.Xr zip_fdopen 3
 .Sh AUTHORS
 .An -nosplit
 .An Dieter Baron Aq dillo@giga.or.at
diff --git a/man/zip_rename.man b/man/zip_rename.man
index 2f1acd6..baf95c7 100644
--- a/man/zip_rename.man
+++ b/man/zip_rename.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_rename.mdoc,v 1.7 2005/06/09 21:13:12 wiz Exp 
-.\" $NiH: zip_rename.mdoc,v 1.7 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_rename.mdoc \-- rename file in zip archive
 .\" Copyright (C) 2003-2008 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_rename.mdoc b/man/zip_rename.mdoc
index 579732e..9c80a1b 100644
--- a/man/zip_rename.mdoc
+++ b/man/zip_rename.mdoc
@@ -1,7 +1,5 @@
-.\" $NiH: zip_rename.mdoc,v 1.7 2005/06/09 21:13:12 wiz Exp $
-.\"
 .\" zip_rename.mdoc -- rename file in zip archive
-.\" Copyright (C) 2003-2008 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2003-2009 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>
@@ -31,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd July 24, 2008
+.Dd March 10, 2009
 .Dt ZIP_RENAME 3
 .Os
 .Sh NAME
@@ -42,7 +40,7 @@
 .Sh SYNOPSIS
 .In zip.h
 .Ft int
-.Fn zip_rename "struct zip *archive" "int index" "const char *name"
+.Fn zip_rename "struct zip *archive" "zip_uint64_t index" "const char *name"
 .Sh DESCRIPTION
 The file at position
 .Ar index
diff --git a/man/zip_set_archive_comment.man b/man/zip_set_archive_comment.man
index 57433a5..d0199e7 100644
--- a/man/zip_set_archive_comment.man
+++ b/man/zip_set_archive_comment.man
@@ -1,6 +1,4 @@
 .\" Converted with mdoc2man 0.2
-.\" from NiH: zip_set_archive_comment.mdoc,v 1.1 2006/04/23 12:47:30 wiz Exp 
-.\" $NiH: zip_set_archive_comment.mdoc,v 1.1 2006/04/23 12:47:30 wiz Exp $
 .\"
 .\" zip_set_archive_comment.mdoc \-- set zip archive comment
 .\" Copyright (C) 2006 Dieter Baron and Thomas Klausner
diff --git a/man/zip_set_file_comment.man b/man/zip_set_file_comment.man
index 8a9d56e..3f1c5ae 100644
--- a/man/zip_set_file_comment.man
+++ b/man/zip_set_file_comment.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_set_file_comment.mdoc,v 1.1 2006/04/23 12:47:30 wiz Exp 
-.\" $NiH: zip_set_file_comment.mdoc,v 1.1 2006/04/23 12:47:30 wiz Exp $
-.\"
 .\" zip_set_file_comment.mdoc \-- set comment for file in zip
 .\" Copyright (C) 2006 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_set_file_comment.mdoc b/man/zip_set_file_comment.mdoc
index 872bc56..068304f 100644
--- a/man/zip_set_file_comment.mdoc
+++ b/man/zip_set_file_comment.mdoc
@@ -1,7 +1,5 @@
-.\" $NiH: zip_set_file_comment.mdoc,v 1.1 2006/04/23 12:47:30 wiz Exp $
-.\"
 .\" zip_set_file_comment.mdoc -- set comment for file in zip
-.\" Copyright (C) 2006 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner
 .\"
 .\" This file is part of libzip, a library to manipulate ZIP files.
 .\" The authors can be contacted at <libzip@nih.at>
@@ -31,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd April 23, 2006
+.Dd March 10, 2009
 .Dt ZIP_SET_FILE_COMMENT 3
 .Os
 .Sh NAME
@@ -42,7 +40,7 @@
 .Sh SYNOPSIS
 .In zip.h
 .Ft int
-.Fn zip_set_file_comment "struct zip *archive" "int index" \
+.Fn zip_set_file_comment "struct zip *archive" "zip_uint64_t index" \
 "const char *comment" "int len"
 .Sh DESCRIPTION
 The
diff --git a/man/zip_source_buffer.man b/man/zip_source_buffer.man
index 38a1378..6711841 100644
--- a/man/zip_source_buffer.man
+++ b/man/zip_source_buffer.man
@@ -1,9 +1,5 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_source_buffer.mdoc,v 1.5 2005/06/09 21:14:54 wiz Exp 
-.\" $NiH: zip_source_buffer.mdoc,v 1.5 2005/06/09 21:14:54 wiz Exp $
-.\"
 .\" zip_source_buffer.mdoc \-- create zip data source from buffer
-.\" Copyright (C) 2004, 2005 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2004-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,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.TH ZIP_SOURCE_DATA 3 "July 20, 2005" NiH
+.TH ZIP_SOURCE_DATA 3 "August 1, 2008" NiH
 .SH "NAME"
 zip_source_buffer \- create zip data source from buffer
 .SH "LIBRARY"
@@ -42,8 +38,8 @@
 #include <zip.h>
 .PP
 struct zip_source *
-zip_source_buffer(struct zip *archive, const void *data, off_t len); \
-"int freep"
+zip_source_buffer(struct zip *archive, const void *data); \
+"zip_uint64_t len" "int freep"
 .SH "DESCRIPTION"
 The function
 zip_source_buffer
@@ -68,8 +64,6 @@
 .TP 4
 [ZIP_ER_INVAL]
 \fBlen\fR
-is negative, or
-\fBlen\fR
 is greater than zero and
 \fBdata\fR
 is
diff --git a/man/zip_source_buffer.mdoc b/man/zip_source_buffer.mdoc
index e251896..9185250 100644
--- a/man/zip_source_buffer.mdoc
+++ b/man/zip_source_buffer.mdoc
@@ -1,7 +1,5 @@
-.\" $NiH: zip_source_buffer.mdoc,v 1.5 2005/06/09 21:14:54 wiz Exp $
-.\"
 .\" zip_source_buffer.mdoc -- create zip data source from buffer
-.\" Copyright (C) 2004, 2005 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2004-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>
@@ -31,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd July 20, 2005
+.Dd August 1, 2008
 .Dt ZIP_SOURCE_DATA 3
 .Os
 .Sh NAME
@@ -42,8 +40,8 @@
 .Sh SYNOPSIS
 .In zip.h
 .Ft struct zip_source *
-.Fn zip_source_buffer "struct zip *archive" "const void *data" "off_t len" \
-"int freep"
+.Fn zip_source_buffer "struct zip *archive" "const void *data" \
+"zip_uint64_t len" "int freep"
 .Sh DESCRIPTION
 The function
 .Fn zip_source_buffer
@@ -67,8 +65,6 @@
 .Bl -tag -width Er
 .It Bq Er ZIP_ER_INVAL
 .Ar len
-is negative, or
-.Ar len
 is greater than zero and
 .Ar data
 is
diff --git a/man/zip_source_file.man b/man/zip_source_file.man
index f3c404a..c3da2f5 100644
--- a/man/zip_source_file.man
+++ b/man/zip_source_file.man
@@ -1,9 +1,5 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_source_file.mdoc,v 1.8 2005/07/15 14:11:16 wiz Exp 
-.\" $NiH: zip_source_file.mdoc,v 1.8 2005/07/15 14:11:16 wiz Exp $
-.\"
 .\" zip_source_file.mdoc \-- create data source from a file
-.\" Copyright (C) 2004, 2005 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2004-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,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.TH ZIP_SOURCE_FILE 3 "July 20, 2005" NiH
+.TH ZIP_SOURCE_FILE 3 "August 1, 2008" NiH
 .SH "NAME"
 zip_source_file \- create data source from a file
 .SH "LIBRARY"
@@ -41,7 +37,8 @@
 .SH "SYNOPSIS"
 .PP
 struct zip_source *
-zip_source_file(struct zip *archive, const char *fname, off_t start, off_t len);
+zip_source_file(struct zip *archive, const char *fname); \
+"zip_uint64_t start" "zip_int64_t len"
 .SH "DESCRIPTION"
 The function
 zip_source_file
@@ -59,6 +56,9 @@
 is 0 or \-1, the whole file (starting from
 \fBstart )\fR
 is used.
+.PP
+The fie is opened and read when the data from the source is used, usually by
+zip_close.
 .SH "RETURN VALUES"
 Upon successful completion, the created source is returned.
 Otherwise,
diff --git a/man/zip_source_file.mdoc b/man/zip_source_file.mdoc
index d5fdd34..823dfb9 100644
--- a/man/zip_source_file.mdoc
+++ b/man/zip_source_file.mdoc
@@ -1,7 +1,5 @@
-.\" $NiH: zip_source_file.mdoc,v 1.8 2005/07/15 14:11:16 wiz Exp $
-.\"
 .\" zip_source_file.mdoc -- create data source from a file
-.\" Copyright (C) 2004, 2005 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2004-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>
@@ -31,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd July 20, 2005
+.Dd August 1, 2008
 .Dt ZIP_SOURCE_FILE 3
 .Os
 .Sh NAME
@@ -41,7 +39,8 @@
 libzip (-lzip)
 .Sh SYNOPSIS
 .Ft struct zip_source *
-.Fn zip_source_file "struct zip *archive" "const char *fname" "off_t start" "off_t len"
+.Fn zip_source_file "struct zip *archive" "const char *fname" \
+"zip_uint64_t start" "zip_int64_t len"
 .Sh DESCRIPTION
 The function
 .Fn zip_source_file
@@ -59,6 +58,9 @@
 is 0 or \-1, the whole file (starting from
 .Ar start )
 is used.
+.Pp
+The fie is opened and read when the data from the source is used, usually by
+.Fn zip_close .
 .Sh RETURN VALUES
 Upon successful completion, the created source is returned.
 Otherwise,
diff --git a/man/zip_source_filep.man b/man/zip_source_filep.man
index fee3c11..e376cde 100644
--- a/man/zip_source_filep.man
+++ b/man/zip_source_filep.man
@@ -1,9 +1,5 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_source_filep.mdoc,v 1.6 2005/06/09 21:14:54 wiz Exp 
-.\" $NiH: zip_source_filep.mdoc,v 1.6 2005/06/09 21:14:54 wiz Exp $
-.\"
 .\" zip_source_filep.mdoc \-- create data source from a file stream
-.\" Copyright (C) 2004, 2005 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2004-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,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.TH ZIP_SOURCE_FILEP 3 "July 20, 2005" NiH
+.TH ZIP_SOURCE_FILEP 3 "August 1, 2008" NiH
 .SH "NAME"
 zip_source_filep \- create data source from FILE *
 .SH "LIBRARY"
@@ -41,7 +37,8 @@
 .SH "SYNOPSIS"
 .PP
 struct zip_source *
-zip_source_filep(struct zip *archive, FILE *file, off_t start, off_t len);
+zip_source_filep(struct zip *archive, FILE *file); \
+"zip_uint64_t start" "zip_int64_t len"
 .SH "DESCRIPTION"
 The function
 zip_source_filep
diff --git a/man/zip_source_filep.mdoc b/man/zip_source_filep.mdoc
index f3d57ec..16d9d5a 100644
--- a/man/zip_source_filep.mdoc
+++ b/man/zip_source_filep.mdoc
@@ -1,7 +1,5 @@
-.\" $NiH: zip_source_filep.mdoc,v 1.6 2005/06/09 21:14:54 wiz Exp $
-.\"
 .\" zip_source_filep.mdoc -- create data source from a file stream
-.\" Copyright (C) 2004, 2005 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2004-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>
@@ -31,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd July 20, 2005
+.Dd August 1, 2008
 .Dt ZIP_SOURCE_FILEP 3
 .Os
 .Sh NAME
@@ -41,7 +39,8 @@
 libzip (-lzip)
 .Sh SYNOPSIS
 .Ft struct zip_source *
-.Fn zip_source_filep "struct zip *archive" "FILE *file" "off_t start" "off_t len"
+.Fn zip_source_filep "struct zip *archive" "FILE *file" \
+"zip_uint64_t start" "zip_int64_t len"
 .Sh DESCRIPTION
 The function
 .Fn zip_source_filep
diff --git a/man/zip_source_free.man b/man/zip_source_free.man
index 2195790..e1e10f3 100644
--- a/man/zip_source_free.man
+++ b/man/zip_source_free.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_source_free.mdoc,v 1.6 2005/06/09 21:14:54 wiz Exp 
-.\" $NiH: zip_source_free.mdoc,v 1.6 2005/06/09 21:14:54 wiz Exp $
-.\"
 .\" zip_source_free.mdoc \-- free zip data source
 .\" Copyright (C) 2004, 2005, 2006 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_source_free.mdoc b/man/zip_source_free.mdoc
index 3ec3325..f631a2f 100644
--- a/man/zip_source_free.mdoc
+++ b/man/zip_source_free.mdoc
@@ -1,5 +1,3 @@
-.\" $NiH: zip_source_free.mdoc,v 1.6 2005/06/09 21:14:54 wiz Exp $
-.\"
 .\" zip_source_free.mdoc -- free zip data source
 .\" Copyright (C) 2004, 2005, 2006 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_source_function.man b/man/zip_source_function.man
index fef0dac..46d50d7 100644
--- a/man/zip_source_function.man
+++ b/man/zip_source_function.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_source_function.mdoc,v 1.17 2006/12/16 10:12:58 wiz Exp 
-.\" $NiH: zip_source_function.mdoc,v 1.17 2006/12/16 10:12:58 wiz Exp $
-.\"
 .\" zip_source_function.mdoc \-- create data source from function
 .\" Copyright (C) 2004-2006 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_source_function.mdoc b/man/zip_source_function.mdoc
index c2c557f..5fbfef8 100644
--- a/man/zip_source_function.mdoc
+++ b/man/zip_source_function.mdoc
@@ -1,7 +1,5 @@
-.\" $NiH: zip_source_function.mdoc,v 1.17 2006/12/16 10:12:58 wiz Exp $
-.\"
 .\" zip_source_function.mdoc -- create data source from function
-.\" Copyright (C) 2004-2006 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2004-2009 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>
@@ -31,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd March 4, 2007
+.Dd March 30, 2009
 .Dt ZIP_SOURCE_FUNCTION 3
 .Os
 .Sh NAME
@@ -50,8 +48,8 @@
 .Ar fn ,
 which must be of the following type:
 .Bd -literal
-typedef ssize_t (*zip_source_callback)(void *state,
-    void *data, size_t len, enum zip_source_cmd cmd);
+typedef zip_int64_t (*zip_source_callback)(void *state,
+    void *data, zip_uint64_t len, enum zip_source_cmd cmd);
 .Ed
 .Pp
 When called by the library, the first argument is the
@@ -82,15 +80,17 @@
 on success, \-1 on error.
 .It Dv ZIP_SOURCE_CLOSE
 Reading is done.
+Return 0.
 .It Dv ZIP_SOURCE_STAT
 Get meta information for the input data.
 .Ar data
-points to a struct zip_stat, which should be filled in.
+points to an initialized
+.Vt struct zip_stat ,
+which should be filled in.
 (See
 .Xr zip_stat_init 3 . )
-Usually, for uncompressed data, after
-.Xr zip_stat_init 3 ,
-only the mtime and size struct members will need to be set.
+Information only available after the source has been read (e.g. size)
+can be omitted in an earlier call.
 Return sizeof(struct zip_stat) on success, \-1 on error.
 .It Dv ZIP_SOURCE_ERROR
 Get error information.
@@ -125,7 +125,13 @@
 will only be issued in response to the function
 returning \-1.
 .Dv ZIP_SOURCE_FREE
-will be the last command issued.
+will be the last command issued;
+if
+.Dv ZIP_SOURCE_OPEN
+was called and succeeded,
+.Dv ZIP_SOURCE_CLOSE
+will be called before
+.Dv ZIP_SOURCE_FREE .
 .Sh RETURN VALUES
 Upon successful completion, the created source is returned.
 Otherwise,
@@ -152,6 +158,6 @@
 .Xr zip_stat_init 3
 .Sh AUTHORS
 .An -nosplit
-.An Dieter Baron Aq dillo@giga.or.at
+.An Dieter Baron Aq dillo@nih.at
 and
 .An Thomas Klausner Aq tk@giga.or.at
diff --git a/man/zip_source_zip.mdoc b/man/zip_source_zip.mdoc
index 6f9e136..8169a0c 100644
--- a/man/zip_source_zip.mdoc
+++ b/man/zip_source_zip.mdoc
@@ -41,7 +41,7 @@
 .In zip.h
 .Ft struct zip_source *
 .Fn zip_source_zip "struct zip *archive" "struct zip *srcarchive" \
-"int srcidx" "int flags" "off_t start" "off_t len"
+"zip_uint64_t srcidx" "int flags" "zip_uint64_t start" "zip_int64_t len"
 .Sh DESCRIPTION
 The function
 .Fn zip_source_zip
diff --git a/man/zip_stat.man b/man/zip_stat.man
index 82e4e30..4dd1ebc 100644
--- a/man/zip_stat.man
+++ b/man/zip_stat.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_stat.mdoc,v 1.12 2006/12/16 10:12:58 wiz Exp 
-.\" $NiH: zip_stat.mdoc,v 1.12 2006/12/16 10:12:58 wiz Exp $
-.\"
 .\" zip_stat.mdoc \-- get information about file
 .\" Copyright (C) 2003, 2004, 2005, 2006 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_stat.mdoc b/man/zip_stat.mdoc
index c63930f..3fc728a 100644
--- a/man/zip_stat.mdoc
+++ b/man/zip_stat.mdoc
@@ -1,7 +1,5 @@
-.\" $NiH: zip_stat.mdoc,v 1.12 2006/12/16 10:12:58 wiz Exp $
-.\"
 .\" zip_stat.mdoc -- get information about file
-.\" Copyright (C) 2003, 2004, 2005, 2006 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2003-2009 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>
@@ -31,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd December 16, 2006
+.Dd March 30, 2009
 .Dt ZIP_STAT 3
 .Os
 .Sh NAME
@@ -77,16 +75,24 @@
 (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 */
-    unsigned short encryption_method;	/* encryption method used */
+    zip_uint64_t valid;                 /* which fields have valid values */
+    const char *name;                   /* name of the file */
+    zip_uint64_t index;                 /* index within archive */
+    zip_uint64_t size;                  /* size of file (uncompressed) */
+    zip_uint64_t comp_size;             /* size of file (compressed) */
+    time_t mtime;                       /* modification time */
+    zip_uint32_t crc;                   /* crc of file data */
+    zip_uint16_t comp_method;           /* compression method used */
+    zip_uint16_t encryption_method;     /* encryption method used */
 };
 .Ed
+.\" XXX: document valid
+The structure pointed to by
+.Ar sb
+must be allocated before calling
+.Fn zip_stat
+or
+.Fn zip_stat_index .
 .Sh RETURN VALUES
 Upon successful completion 0 is returned.
 Otherwise, \-1 is returned and the error information in
diff --git a/man/zip_stat_init.man b/man/zip_stat_init.man
index 8202c86..44d8849 100644
--- a/man/zip_stat_init.man
+++ b/man/zip_stat_init.man
@@ -1,5 +1,3 @@
-.\" $NiH$
-.\"
 .\" zip_stat_init.mdoc \-- init zip_stat structure
 .\" Copyright (C) 2006 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_stat_init.mdoc b/man/zip_stat_init.mdoc
index 5807891..6ad7134 100644
--- a/man/zip_stat_init.mdoc
+++ b/man/zip_stat_init.mdoc
@@ -1,7 +1,5 @@
-.\" $NiH$
-.\"
 .\" zip_stat_init.mdoc -- init zip_stat structure
-.\" Copyright (C) 2006 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>
@@ -31,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd December 16, 2006
+.Dd November 10, 2008
 .Dt ZIP_STAT_INIT 3
 .Os
 .Sh NAME
@@ -51,6 +49,10 @@
 .Xr zip_stat 3 ,
 but this function should be used to initialize it to
 make sure none are missed.
+The structure pointed to by
+.Ar sb
+must be allocated before calling
+.Fn zip_stat_init .
 .Sh RETURN VALUES
 If
 .Ar sb
diff --git a/man/zip_unchange.man b/man/zip_unchange.man
index 2b10867..3db8e41 100644
--- a/man/zip_unchange.man
+++ b/man/zip_unchange.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_unchange.mdoc,v 1.11 2005/06/09 21:14:54 wiz Exp 
-.\" $NiH: zip_unchange.mdoc,v 1.11 2005/06/09 21:14:54 wiz Exp $
-.\"
 .\" zip_unchange.mdoc \-- undo changes to file in zip archive
 .\" Copyright (C) 2003, 2005, 2006 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_unchange.mdoc b/man/zip_unchange.mdoc
index 7359d89..4eed1b2 100644
--- a/man/zip_unchange.mdoc
+++ b/man/zip_unchange.mdoc
@@ -1,5 +1,3 @@
-.\" $NiH: zip_unchange.mdoc,v 1.11 2005/06/09 21:14:54 wiz Exp $
-.\"
 .\" zip_unchange.mdoc -- undo changes to file in zip archive
 .\" Copyright (C) 2003, 2005, 2006 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_unchange_all.man b/man/zip_unchange_all.man
index 5edfb33..44ed043 100644
--- a/man/zip_unchange_all.man
+++ b/man/zip_unchange_all.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_unchange_all.mdoc,v 1.10 2005/06/09 21:14:54 wiz Exp 
-.\" $NiH: zip_unchange_all.mdoc,v 1.10 2005/06/09 21:14:54 wiz Exp $
-.\"
 .\" zip_unchange_all.mdoc \-- undo changes to all files in zip archive
 .\" Copyright (C) 2003, 2005, 2006 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_unchange_all.mdoc b/man/zip_unchange_all.mdoc
index 9adaaed..efab2e8 100644
--- a/man/zip_unchange_all.mdoc
+++ b/man/zip_unchange_all.mdoc
@@ -1,5 +1,3 @@
-.\" $NiH: zip_unchange_all.mdoc,v 1.10 2005/06/09 21:14:54 wiz Exp $
-.\"
 .\" zip_unchange_all.mdoc -- undo changes to all files in zip archive
 .\" Copyright (C) 2003, 2005, 2006 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_unchange_archive.man b/man/zip_unchange_archive.man
index 1f03b06..772ae0e 100644
--- a/man/zip_unchange_archive.man
+++ b/man/zip_unchange_archive.man
@@ -1,7 +1,3 @@
-.\" Converted with mdoc2man 0.2
-.\" from NiH: zip_unchange_all.mdoc,v 1.10 2005/06/09 21:14:54 wiz Exp 
-.\" $NiH: zip_unchange_all.mdoc,v 1.10 2005/06/09 21:14:54 wiz Exp $
-.\"
 .\" zip_unchange_archive.mdoc \-- undo changes to all files in zip archive
 .\" Copyright (C) 2006-2008 Dieter Baron and Thomas Klausner
 .\"
diff --git a/man/zip_unchange_archive.mdoc b/man/zip_unchange_archive.mdoc
index dc331b3..753448a 100644
--- a/man/zip_unchange_archive.mdoc
+++ b/man/zip_unchange_archive.mdoc
@@ -1,5 +1,3 @@
-.\" $NiH: zip_unchange_all.mdoc,v 1.10 2005/06/09 21:14:54 wiz Exp $
-.\"
 .\" zip_unchange_archive.mdoc -- undo changes to all files in zip archive
 .\" Copyright (C) 2006-2008 Dieter Baron and Thomas Klausner
 .\"
diff --git a/regress/CMakeLists.txt b/regress/CMakeLists.txt
index 0a589f3..6f1fdee 100644
--- a/regress/CMakeLists.txt
+++ b/regress/CMakeLists.txt
@@ -1,5 +1,3 @@
-# $NiH$
-
 ENABLE_TESTING()
 
 SET(TEST_PROGRAMS
@@ -24,4 +22,5 @@
   ADD_TEST(${PROGRAM} ${CMAKE_CURRENT_SOURCE_DIR}/runtest ${CMAKE_CURRENT_SOURCE_DIR}/${PROGRAM})
 ENDFOREACH(PROGRAM ${TEST_PROGRAMS})
 
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../lib)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../lib
+	${CMAKE_CURRENT_BINARY_DIR}/..)
diff --git a/regress/add_from_buffer.c b/regress/add_from_buffer.c
index baee8f6..40efd21 100644
--- a/regress/add_from_buffer.c
+++ b/regress/add_from_buffer.c
@@ -1,6 +1,4 @@
 /*
-  $NiH: add_from_buffer.c,v 1.2 2006/02/21 09:41:13 dillo Exp $
-
   add_from_buffer.c -- test case for adding file from buffer to archive
   Copyright (C) 1999, 2003, 2005 Dieter Baron and Thomas Klausner
 
diff --git a/regress/add_from_buffer.test b/regress/add_from_buffer.test
index c6e75a0..ff6c472 100644
--- a/regress/add_from_buffer.test
+++ b/regress/add_from_buffer.test
@@ -1,5 +1,4 @@
 # add buffer contents as file to zip
-# $NiH: add_from_buffer.test,v 1.1 2005/07/15 16:54:25 wiz Exp $
 program add_from_buffer
 return 0
 args testbuffer.zip
diff --git a/regress/add_from_file.c b/regress/add_from_file.c
index 13141a1..cbcf5d9 100644
--- a/regress/add_from_file.c
+++ b/regress/add_from_file.c
@@ -1,6 +1,4 @@
 /*
-  $NiH: add_from_file.c,v 1.1 2005/07/15 16:53:37 wiz Exp $
-
   add_from_file.c -- test case for adding file to archive
   Copyright (C) 1999, 2003, 2005 Dieter Baron and Thomas Klausner
 
diff --git a/regress/add_from_file.test b/regress/add_from_file.test
index 35e9ac3..279fbe1 100644
--- a/regress/add_from_file.test
+++ b/regress/add_from_file.test
@@ -1,5 +1,4 @@
 # add file to zip
-# $NiH: add_from_file.test,v 1.1 2005/07/15 16:54:25 wiz Exp $
 program add_from_file
 return 0
 args testfile.zip testfile.txt
diff --git a/regress/add_from_filep.c b/regress/add_from_filep.c
index ab83db0..059e957 100644
--- a/regress/add_from_filep.c
+++ b/regress/add_from_filep.c
@@ -1,6 +1,4 @@
 /*
-  $NiH: add_from_filep.c,v 1.1 2005/07/17 00:01:06 wiz Exp $
-
   add_from_filep.c -- test case for adding file to archive
   Copyright (C) 1999, 2003, 2005 Dieter Baron and Thomas Klausner
 
diff --git a/regress/add_from_filep.test b/regress/add_from_filep.test
index 48f7edc..3a2a8cf 100644
--- a/regress/add_from_filep.test
+++ b/regress/add_from_filep.test
@@ -1,5 +1,4 @@
 # add file to zip
-# $NiH: add_from_filep.test,v 1.1 2005/07/17 00:01:06 wiz Exp $
 program add_from_filep
 return 0
 args testfile.zip testfile.txt
diff --git a/regress/broken.zip b/regress/broken.zip
index 6dbff3e..2008c32 100644
--- a/regress/broken.zip
+++ b/regress/broken.zip
Binary files differ
diff --git a/regress/encrypt.c b/regress/encrypt.c
index 832d0d1..d5b00ca 100644
--- a/regress/encrypt.c
+++ b/regress/encrypt.c
@@ -1,6 +1,4 @@
 /*
-  $NiH$
-
   encrypt.c -- test encryption support
   Copyright (C) 2006 Dieter Baron and Thomas Klausner
 
diff --git a/regress/encrypt.test b/regress/encrypt.test
index 6fb7371..ba6502f 100644
--- a/regress/encrypt.test
+++ b/regress/encrypt.test
@@ -1,5 +1,4 @@
 # test encryption support
-# $NiH$
 program encrypt
 return 0
 args encrypt.zip
diff --git a/regress/fread.c b/regress/fread.c
index 85f4e74..9080b8a 100644
--- a/regress/fread.c
+++ b/regress/fread.c
@@ -1,8 +1,6 @@
 /*
-  $NiH: fread.c,v 1.6 2006/02/21 10:21:25 dillo Exp $
-
   fread.c -- test cases for reading from zip archives
-  Copyright (C) 2004, 2005, 2006 Dieter Baron and Thomas Klausner
+  Copyright (C) 2004-2009 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>
@@ -95,6 +93,13 @@
 		    WHEN_READ, ZIP_ER_CRC, 0);
     fail += do_read(z, "storedok", ZIP_FL_COMPRESSED, WHEN_NEVER, 0, 0);
 
+    fail += do_read(z, "cryptok", 0, WHEN_OPEN, ZIP_ER_NOPASSWD, 0);
+    zip_set_default_password(z, "crypt");
+    fail += do_read(z, "cryptok", 0, WHEN_NEVER, 0, 0);
+    zip_set_default_password(z, "wrong");
+    fail += do_read(z, "cryptok", 0, WHEN_OPEN, ZIP_ER_WRONGPASSWD, 0);
+    zip_set_default_password(z, NULL);
+
     zs = zip_source_buffer(z, "asdf", 4, 0);
     zip_replace(z, zip_name_locate(z, "storedok", 0), zs);
     fail += do_read(z, "storedok", 0, WHEN_OPEN, ZIP_ER_CHANGED, 0);
@@ -154,11 +159,14 @@
     if (when_got != when_ex || ze_got != ze_ex || se_got != se_ex) {
 	zip_error_to_str(expected, sizeof(expected), ze_ex, se_ex);
 	zip_error_to_str(got, sizeof(got), ze_got, se_got);
-	printf("%s: got %s error (%s), expected %s error (%s)\n", prg,
+	printf("%s: %s: got %s error (%s), expected %s error (%s)\n",
+	       prg, name,
 	       when_name[when_got], got, 
 	       when_name[when_ex], expected);
 	return 1;
     }
+    else if (getenv("VERBOSE"))
+	printf("%s: %s: passed\n", prg, name);
 
     return 0;
 }
diff --git a/regress/fread.test b/regress/fread.test
index 9fbe5d8..234e1a1 100644
--- a/regress/fread.test
+++ b/regress/fread.test
@@ -1,5 +1,4 @@
 # various tests for zip_fread
-# $NiH: fread.test,v 1.1 2005/07/16 17:14:32 wiz Exp $
 program fread
 args broken.zip
 return 0
diff --git a/regress/get_comment.c b/regress/get_comment.c
index 7df1e3c..62a521f 100644
--- a/regress/get_comment.c
+++ b/regress/get_comment.c
@@ -1,6 +1,4 @@
 /*
-  $NiH: get_comment.c,v 1.3 2006/04/23 14:17:36 wiz Exp $
-
   comment.c -- test cases for file and archive comments
   Copyright (C) 2006 Dieter Baron and Thomas Klausner
 
diff --git a/regress/get_comment.test b/regress/get_comment.test
index e2cb829..a7b22ea 100644
--- a/regress/get_comment.test
+++ b/regress/get_comment.test
@@ -1,5 +1,4 @@
 # show comments of a zip archive
-# $NiH: comment.test,v 1.1 2006/04/09 19:05:48 wiz Exp $
 program get_comment
 return 0
 args testcomment.zip
diff --git a/regress/mkname.c b/regress/mkname.c
index ba4452b..647e836 100644
--- a/regress/mkname.c
+++ b/regress/mkname.c
@@ -1,6 +1,4 @@
 /*
-  $NiH: mkname.c,v 1.1 2005/06/09 18:49:38 dillo Exp $
-
   mkname.c -- add srcdir to name
   Copyright (C) 2005 Dieter Baron and Thomas Klausner
 
diff --git a/regress/name_locate.c b/regress/name_locate.c
index dc14524..62d3714 100644
--- a/regress/name_locate.c
+++ b/regress/name_locate.c
@@ -1,6 +1,4 @@
 /*
-  $NiH: name_locate.c,v 1.6 2006/02/21 09:41:13 dillo Exp $
-
   name_locate.c -- test cases for finding files in zip archives
   Copyright (C) 2005-2006 Dieter Baron and Thomas Klausner
 
diff --git a/regress/name_locate.test b/regress/name_locate.test
index e664fd7..5b5bde0 100644
--- a/regress/name_locate.test
+++ b/regress/name_locate.test
@@ -1,5 +1,4 @@
 # various tests for zip_name_locate
-# $NiH: name_locate.test,v 1.1 2005/07/16 17:14:32 wiz Exp $
 program name_locate
 args test.zip
 return 0
diff --git a/regress/open.c b/regress/open.c
index 6b6c18c..78663ba 100644
--- a/regress/open.c
+++ b/regress/open.c
@@ -1,6 +1,4 @@
 /*
-  $NiH: open.c,v 1.6 2005/07/16 17:14:32 wiz Exp $
-
   open.c -- test cases for opening zip archives
   Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner
 
diff --git a/regress/open.test b/regress/open.test
index b843cd4..c4b6a3a 100644
--- a/regress/open.test
+++ b/regress/open.test
@@ -1,5 +1,4 @@
 # various tests for zip_open
-# $NiH: open.test,v 1.1 2005/07/16 17:14:32 wiz Exp $
 program open
 args test.zip Makefile.am
 return 0
diff --git a/regress/set_comment_all.c b/regress/set_comment_all.c
index e187a7a..489a272 100644
--- a/regress/set_comment_all.c
+++ b/regress/set_comment_all.c
@@ -1,6 +1,4 @@
 /*
-  $NiH: set_comment_all.c,v 1.2 2006/04/23 13:28:41 wiz Exp $
-
   set_comment_all.c -- set global and file comments
   Copyright (C) 2006 Dieter Baron and Thomas Klausner
 
diff --git a/regress/set_comment_all.test b/regress/set_comment_all.test
index a1b9c5c..2369ae8 100644
--- a/regress/set_comment_all.test
+++ b/regress/set_comment_all.test
@@ -1,5 +1,4 @@
 # change local and global comments in a zip archive
-# $NiH: set_comment.test,v 1.1 2006/04/23 00:39:58 wiz Exp $
 program set_comment_all
 return 0
 # need filename extension != zip to avoid using zipcmp,
diff --git a/regress/set_comment_localonly.c b/regress/set_comment_localonly.c
index f11416e..55e25d3 100644
--- a/regress/set_comment_localonly.c
+++ b/regress/set_comment_localonly.c
@@ -1,6 +1,4 @@
 /*
-  $NiH: set_comment_localonly.c,v 1.3 2006/04/23 13:28:41 wiz Exp $
-
   set_comment_localonly.c -- set file comments
   Copyright (C) 2006 Dieter Baron and Thomas Klausner
 
diff --git a/regress/set_comment_localonly.test b/regress/set_comment_localonly.test
index 269f9c9..8ff58eb 100644
--- a/regress/set_comment_localonly.test
+++ b/regress/set_comment_localonly.test
@@ -1,5 +1,4 @@
 # change local comments in a zip archive
-# $NiH: set_comment.test,v 1.1 2006/04/23 00:39:58 wiz Exp $
 program set_comment_localonly
 return 0
 # need filename extension != zip to avoid using zipcmp,
diff --git a/regress/set_comment_removeglobal.c b/regress/set_comment_removeglobal.c
index c6cb4cc..c8ff6c5 100644
--- a/regress/set_comment_removeglobal.c
+++ b/regress/set_comment_removeglobal.c
@@ -1,6 +1,4 @@
 /*
-  $NiH: set_comment_removeglobal.c,v 1.1 2006/04/23 13:28:31 wiz Exp $
-
   set_comment_removeglobal.c -- remove archive comment
   Copyright (C) 2006 Dieter Baron and Thomas Klausner
 
diff --git a/regress/set_comment_removeglobal.test b/regress/set_comment_removeglobal.test
index 091fa70..14c504e 100644
--- a/regress/set_comment_removeglobal.test
+++ b/regress/set_comment_removeglobal.test
@@ -1,5 +1,4 @@
 # remove archive comment
-# $NiH: set_comment_revert.test,v 1.1 2006/04/23 13:21:19 wiz Exp $
 program set_comment_removeglobal
 return 0
 # need filename extension != zip to avoid using zipcmp,
diff --git a/regress/set_comment_revert.c b/regress/set_comment_revert.c
index 2c7618b..46a1b85 100644
--- a/regress/set_comment_revert.c
+++ b/regress/set_comment_revert.c
@@ -1,6 +1,4 @@
 /*
-  $NiH: set_comment_revert.c,v 1.2 2006/04/23 13:28:41 wiz Exp $
-
   set_comment_revert.c -- set global and file comments, but revert
   Copyright (C) 2006 Dieter Baron and Thomas Klausner
 
diff --git a/regress/set_comment_revert.test b/regress/set_comment_revert.test
index 2d83f0c..d702060 100644
--- a/regress/set_comment_revert.test
+++ b/regress/set_comment_revert.test
@@ -1,5 +1,4 @@
 # start changing local and global comments, but revert before closing
-# $NiH: set_comment_all.test,v 1.1 2006/04/23 12:25:00 wiz Exp $
 program set_comment_revert
 return 0
 # need filename extension != zip to avoid using zipcmp,
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c5b76a4..f7b877f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,10 +1,14 @@
-# $NiH$
-
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../lib
   ${CMAKE_CURRENT_BINARY_DIR}/..)
 
 ADD_EXECUTABLE(zipcmp zipcmp.c)
 TARGET_LINK_LIBRARIES(zipcmp zip)
+INSTALL(TARGETS zipcmp RUNTIME DESTINATION bin)
 
 ADD_EXECUTABLE(zipmerge zipmerge.c)
 TARGET_LINK_LIBRARIES(zipmerge zip)
+INSTALL(TARGETS zipmerge RUNTIME DESTINATION bin)
+
+ADD_EXECUTABLE(ziptorrent ziptorrent.c)
+TARGET_LINK_LIBRARIES(ziptorrent zip)
+INSTALL(TARGETS ziptorrent RUNTIME DESTINATION bin)