+
+#ifndef offsetof
+#pragma warning had to DEFINE offsetof as it was not in stddef.h
+#define offsetof(T,M) ((unsigned)(& ((T*)0)->M))
+#endif
+
+#ifdef ZZIP_HAVE_SYS_STAT_H
+/* MSVC does have IFbitmask but not the corresponding IStests */
+# if !defined S_ISDIR && defined S_IFDIR
+# define S_ISDIR(_X_) ((_X_) & S_IFDIR)
+# endif
+# if !defined S_ISREG && defined S_IFREG
+# define S_ISREG(_X_) ((_X_) & S_IFREG)
+# endif
+#endif
+
+/**
+ * This function is the equivalent of a => rewinddir(2) for a realdir or
+ * the zipfile in place of a directory. The ZZIP_DIR handle returned from
+ * => zzip_opendir has a flag saying realdir or zipfile. As for a zipfile,
+ * the filenames will include the filesubpath, so take care.
+ */
+void
+zzip_rewinddir(ZZIP_DIR * dir)
+{
+ if (! dir) return;
+
+ if (USE_DIRENT && dir->realdir)
+ {
+ _zzip_rewinddir(dir->realdir);
+ return;
+ }
+
+ if (dir->hdr0)
+ dir->hdr = dir->hdr0;
+ else
+ dir->hdr = 0;
+}
+
+#if ! USE_DIRENT
+#define real_readdir(_X_) 1
+#else
+static int
+real_readdir(ZZIP_DIR* dir)
+{
+ struct stat st = { 0 };
+ char filename[PATH_MAX];
+ struct dirent* dirent = _zzip_readdir(dir->realdir);
+ if (! dirent) return 0;
+
+ dir->dirent.d_name = dirent->d_name;
+ strcpy(filename, dir->realname);
+ strcat(filename, "/");
+ strcat(filename, dirent->d_name);
+
+ if (stat(filename, &st) == -1)
+ return -1;
+
+ dir->dirent.d_csize = dir->dirent.st_size = st.st_size;
+
+ if (st.st_mode)
+ {
+ if (! S_ISREG(st.st_mode))
+ {
+ dir->dirent.d_compr = st.st_mode;
+ dir->dirent.d_compr |= 0x80000000;
+ /* makes it effectively negative,
+ * but can still be fed to S_ISXXX(x) */
+ }else
+ {
+ dir->dirent.d_compr = 0; /* stored */
+ }
+ }else
+ {
+ dir->dirent.d_compr = 0; /* stored */
+ }
+
+ return 1;
+}
+#endif
+
+/**
+ * This function is the equivalent of a => readdir(2) for a realdir
+ * or a zipfile referenced by the ZZIP_DIR returned from => zzip_opendir.
+ *
+ * The ZZIP_DIR handle (as returned by => zzip_opendir) contains a few more
+ * entries than being copied into the ZZIP_DIRENT. The only valid fields in
+ * a ZZIP_DIRENT are d_name (the file name), d_compr (compression), d_csize
+ * (compressed size), st_size (uncompressed size).
+ */
+ZZIP_DIRENT*
+zzip_readdir(ZZIP_DIR * dir)
+{
+ if (! dir) { errno=EBADF; return 0; }
+
+ if (USE_DIRENT && dir->realdir)
+ {
+ if (! real_readdir(dir))
+ return 0;
+ }else
+ {
+ if (! dir->hdr) return 0;
+
+ dir->dirent.d_name = dir->hdr->d_name;
+ dir->dirent.d_compr = dir->hdr->d_compr;
+
+ dir->dirent.d_csize = dir->hdr->d_csize;
+ dir->dirent.st_size = dir->hdr->d_usize;
+
+ if (! dir->hdr->d_reclen) dir->hdr = 0;
+ else dir->hdr = (struct zzip_dir_hdr *)
+ ((char *)dir->hdr + dir->hdr->d_reclen);
+ }
+ return &dir->dirent;
+}
+
+/** => zzip_rewinddir
+ * This function is the equivalent of => telldir(2) for a realdir or zipfile.
+ */
+zzip_off_t
+zzip_telldir(ZZIP_DIR* dir)
+{
+ if (! dir) { errno=EBADF; return -1; }
+
+ if (USE_DIRENT && dir->realdir)
+ {
+ return _zzip_telldir(dir->realdir);
+ }else
+ {
+ return ((zzip_off_t) ((char*) dir->hdr - (char*) dir->hdr0));
+ }
+}
+
+/** => zzip_rewinddir
+ * This function is the equivalent of => seekdir(2) for a realdir or zipfile.
+ */
+void
+zzip_seekdir(ZZIP_DIR* dir, zzip_off_t offset)
+{
+ if (! dir) return;
+
+ if (USE_DIRENT && dir->realdir)
+ {
+ _zzip_seekdir(dir->realdir, offset);
+ }else
+ {
+ dir->hdr = (struct zzip_dir_hdr*)
+ (dir->hdr0 ? (char*) dir->hdr0 + (size_t) offset : 0);
+ }
+}
+
+#if defined ZZIP_LARGEFILE_RENAME && defined EOVERFLOW && defined PIC
+#undef zzip_seekdir /* zzip_seekdir64 */
+#undef zzip_telldir /* zzip_telldir64 */
+
+long zzip_telldir(ZZIP_DIR* dir)
+{
+ off_t off = zzip_telldir64 (dir);
+ long offs = off;
+ if (offs != off) { errno = EOVERFLOW; return -1; }
+ return offs;
+}
+
+void zzip_seekdir(ZZIP_DIR* dir, long offset)
+{
+ zzip_seekdir64 (dir, offset);
+}
+#endif
+
+/**
+ * This function is the equivalent of => opendir(3) for a realdir or zipfile.
+ *
+ * This function has some magic - if the given argument-path
+ * is a directory, it will wrap a real => opendir(3) into the ZZIP_DIR
+ * structure. Otherwise it will divert to => zzip_dir_open which
+ * can also attach a ".zip" extension if needed to find the archive.
+ *
+ * the error-code is mapped to => errno(3).
+ */
+ZZIP_DIR*
+zzip_opendir(zzip_char_t* filename)
+{
+ return zzip_opendir_ext_io (filename, 0, 0, 0);
+}
+
+/** => zzip_opendir
+ * This function uses explicit ext and io instead of the internal
+ * defaults, setting them to zero is equivalent to => zzip_opendir
+ */
+ZZIP_DIR*
+zzip_opendir_ext_io(zzip_char_t* filename, int o_modes,
+ zzip_strings_t* ext, zzip_plugin_io_t io)
+{
+ zzip_error_t e;
+ ZZIP_DIR* dir;
+
+# ifdef ZZIP_HAVE_SYS_STAT_H
+ struct stat st;
+# endif
+
+ if (o_modes & (ZZIP_PREFERZIP|ZZIP_ONLYZIP)) goto try_zzip;
+ try_real:
+
+# ifdef ZZIP_HAVE_SYS_STAT_H
+ if (stat(filename, &st) >= 0 && S_ISDIR(st.st_mode)
+ ){
+ if (USE_DIRENT)
+ {
+ _zzip_DIR* realdir = _zzip_opendir(filename);
+ if (realdir)
+ {
+ if (! (dir = (ZZIP_DIR *)calloc(1, sizeof (*dir))))
+ {
+ _zzip_closedir(realdir);
+ return 0;
+ }else
+ {
+ dir->realdir = realdir;
+ dir->realname = strdup(filename);
+ return dir;
+ }
+ }
+ }
+ return 0;
+ }
+# endif /* HAVE_SYS_STAT_H */
+
+ try_zzip:
+ dir = zzip_dir_open_ext_io (filename, &e, ext, io);
+ if (! dir && (o_modes & ZZIP_PREFERZIP)) goto try_real;
+ if (e) errno = zzip_errno(e);
+ return dir;
+}
+
+/**
+ * This function is the equivalent of => closedir(3) for a realdir or zipfile.
+ *
+ * This function is magic - if the given arg-ZZIP_DIR
+ * is a real directory, it will call the real => closedir(3) and then
+ * free the wrapping ZZIP_DIR structure. Otherwise it will divert
+ * to => zzip_dir_close which will free the ZZIP_DIR structure.
+ */
+int
+zzip_closedir(ZZIP_DIR* dir)
+{
+ if (! dir) { errno = EBADF; return -1; }
+
+ if (USE_DIRENT && dir->realdir)
+ {
+ _zzip_closedir(dir->realdir);
+ free(dir->realname);
+ free(dir);
+ return 0;
+ }else
+ {
+ zzip_dir_close(dir);
+ return 0;
+ }
+}
+
+/*
+ * Local variables:
+ * c-file-style: "stroustrup"
+ * End:
+ */
diff --git a/zzip/err.c b/zzip/err.c
new file mode 100644
index 0000000..299c44e
--- /dev/null
+++ b/zzip/err.c
@@ -0,0 +1,154 @@
+/*
+ * Author:
+ * Guido Draheim
+ * Tomi Ollila
+ *
+ * Copyright (c) 1999,2000,2001,2002,2003 Guido Draheim
+ * All rights reserved,
+ * use under the restrictions of the
+ * Lesser GNU General Public License
+ * or alternatively the restrictions
+ * of the Mozilla Public License 1.1
+ */
+
+#include /* exported... */
+#include
+
+#include
+#include
+
+#include
+
+static struct errlistentry { int code; const char* mesg; }
+errlist[] =
+{
+ { ZZIP_NO_ERROR, "No error" },
+ { ZZIP_OUTOFMEM, "could not get temporary memory for internal structures" },
+ { ZZIP_DIR_OPEN, "Failed to open zip-file %s" },
+ { ZZIP_DIR_STAT, "Failed to fstat zip-file %s" },
+ { ZZIP_DIR_SEEK, "Failed to lseek zip-file %s" },
+ { ZZIP_DIR_READ, "Failed to read zip-file %s"},
+ { ZZIP_DIR_TOO_SHORT, "zip-file %s too short" },
+ { ZZIP_DIR_EDH_MISSING, "zip-file central directory not found" },
+ { ZZIP_DIRSIZE, "Directory size too big..." },
+ { ZZIP_ENOENT, "No such file found in zip-file %s" },
+ { ZZIP_UNSUPP_COMPR, "Unsupported compression format" },
+ { ZZIP_CORRUPTED, "Zipfile corrupted" },
+ { ZZIP_UNDEF, "Some undefined error occurred" },
+ { 0, 0 },
+};
+
+#define errlistSIZE (sizeof(errlist)/sizeof(*errlist))
+
+/**
+ * returns the static string for the given error code. The
+ * error code can be either a normal system error (a
+ * positive error code will flag this), it can be => libz
+ * error code (a small negative error code will flag this)
+ * or it can be an error code from => libzzip, which is an
+ * negative value lower than => ZZIP_ERROR
+ */
+zzip_char_t*
+zzip_strerror(int errcode)
+{
+ if (errcode < ZZIP_ERROR && errcode > ZZIP_ERROR-32)
+ {
+ struct errlistentry* err = errlist;
+ for (; err->mesg ; err++)
+ {
+ if (err->code == errcode)
+ return err->mesg;
+ }
+ errcode = EINVAL;
+ }
+
+ if (errcode < 0)
+ {
+ if (errcode == -1)
+ return strerror(errcode);
+ else
+ return zError(errcode);
+ }
+
+ return strerror (errcode);
+}
+
+/** => zzip_strerror
+ * This function fetches the errorcode from the => DIR-handle and
+ * runs it through => zzip_strerror to obtain the static string
+ * describing the error.
+ */
+zzip_char_t*
+zzip_strerror_of(ZZIP_DIR* dir)
+{
+ if (! dir) return strerror (errno);
+ return zzip_strerror(dir->errcode);
+}
+
+static struct errnolistentry { int code; int e_no; }
+errnolist[] =
+{
+ { Z_STREAM_ERROR, EPIPE },
+ { Z_DATA_ERROR, ESPIPE },
+ { Z_MEM_ERROR, ENOMEM },
+ { Z_BUF_ERROR, EMFILE },
+ { Z_VERSION_ERROR, ENOEXEC },
+
+ { ZZIP_DIR_OPEN, ENOTDIR },
+ { ZZIP_DIR_STAT, EREMOTE },
+ { ZZIP_DIR_SEEK, ESPIPE },
+# ifdef ESTRPIPE
+ { ZZIP_DIR_READ, ESTRPIPE},
+# else
+ { ZZIP_DIR_READ, EPIPE},
+# endif
+ { ZZIP_DIR_TOO_SHORT, ENOEXEC },
+# ifdef ENOMEDIUM
+ { ZZIP_DIR_EDH_MISSING, ENOMEDIUM },
+# else
+ { ZZIP_DIR_EDH_MISSING, EIO },
+# endif
+ { ZZIP_DIRSIZE, EFBIG },
+ { ZZIP_OUTOFMEM, ENOMEM },
+ { ZZIP_ENOENT, ENOENT },
+# ifdef EPFNOSUPPORT
+ { ZZIP_UNSUPP_COMPR, EPFNOSUPPORT },
+# else
+ { ZZIP_UNSUPP_COMPR, EACCES },
+# endif
+# ifdef EILSEQ
+ { ZZIP_CORRUPTED, EILSEQ },
+# else
+ { ZZIP_CORRUPTED, ELOOP },
+# endif
+ { ZZIP_UNDEF, EINVAL },
+ { 0, 0 },
+};
+
+/**
+ * map the error code to a system error code. This is used
+ * for the drop-in replacement functions to return a value
+ * that can be interpreted correctly by code sections that
+ * are unaware of the fact they their => open(2) call had been
+ * diverted to a file inside a zip-archive.
+ */
+int
+zzip_errno(int errcode)
+{
+ if (errcode >= -1) return errno;
+
+ { struct errnolistentry* err = errnolist;
+ for (; err->code ; err++)
+ {
+ if (err->code == errcode)
+ return err->e_no;
+ }
+ }
+ return EINVAL;
+}
+
+/*
+ * Local variables:
+ * c-file-style: "stroustrup"
+ * End:
+ */
diff --git a/zzip/file.h b/zzip/file.h
new file mode 100644
index 0000000..e3b3497
--- /dev/null
+++ b/zzip/file.h
@@ -0,0 +1,81 @@
+/*
+ * this is an internal header file - the structure contains two off_t
+ * atleast making it LARGEFILE_SENSITIVE on linux2 and solaris systems
+ * whereas about all functions just return a ZZIP_FILE* in zzip/zzip.h
+ *
+ * and so, this structure should be handled version-specific and
+ * subject to change - it had been kept binary-compatible for quite
+ * a while now so perhaps some program sources have errnously taken
+ * advantage of this file.
+ *
+ * Author:
+ * Guido Draheim
+ * Tomi Ollila
+ *
+ * Copyright (c) 1999,2000,2001,2002 Guido Draheim
+ * All rights reserved,
+ * use under the restrictions of the
+ * Lesser GNU General Public License
+ * or alternatively the restrictions
+ * of the Mozilla Public License 1.1
+ */
+
+#ifndef _ZZIP_FILE_H /* zzip-file.h */
+#define _ZZIP_FILE_H 1
+
+#ifndef ZZIP_32K
+#ifdef __GNUC__
+/* include zzip/lib.h beforehand in order to suppress the following warning */
+#warning zzip/file.h is an internal header, do not use it freely
+#endif
+#endif
+
+#include
+#include
+
+#ifdef ZZIP_HAVE_UNISTD_H
+#include
+#else
+#include
+# ifdef ZZIP_HAVE_SYS_TYPES_H
+# include
+# endif
+#endif
+
+#ifdef ZZIP_HAVE_SYS_PARAM_H
+#include /* PATH_MAX */
+#endif
+
+#ifndef PATH_MAX
+# ifdef MAX_PATH /* windows */
+# define PATH_MAX MAX_PATH
+# else
+# define PATH_MAX 512
+# endif
+#endif
+/*
+ * ZZIP_FILE structure... currently no need to unionize, since structure needed
+ * for inflate is superset of structure needed for unstore.
+ *
+ * Don't make this public. Instead, create methods for needed operations.
+ */
+
+struct zzip_file
+{
+ struct zzip_dir* dir;
+ int fd;
+ int method;
+ zzip_size_t restlen;
+ zzip_size_t crestlen;
+ zzip_size_t usize;
+ zzip_size_t csize;
+ /* added dataoffset member - data offset from start of zipfile*/
+ zzip_off_t dataoffset;
+ char* buf32k;
+ zzip_off_t offset; /* offset from the start of zipfile... */
+ z_stream d_stream;
+ zzip_plugin_io_t io;
+};
+
+#endif /* _ZZIP_FILE_H */
+
diff --git a/zzip/format.h b/zzip/format.h
new file mode 100644
index 0000000..06ad5dd
--- /dev/null
+++ b/zzip/format.h
@@ -0,0 +1,159 @@
+/*
+ * Author:
+ * Guido Draheim
+ *
+ * Copyright (c) 2000,2001,2002,2003 Guido Draheim
+ * All rights reserved
+ * use under the restrictions of the
+ * Lesser GNU General Public License
+ * or alternatively the restrictions
+ * of the Mozilla Public License 1.1
+ *
+ * The information was taken from appnote-981119-iz.zip
+ * at http://www.freesoftware.com/pub/infozip/doc/
+ * which in turn is based on PKWARE's appnote.txt
+ */
+#ifndef _ZZIP_FORMAT_H /* zzipformat.h */
+#define _ZZIP_FORMAT_H
+
+#include
+/* we have ICO C 9X types defined */
+
+/*
+ * Overall zipfile format
+ * [local file header + file data + data descriptr] ... [central directory] [EOD record]
+ */
+
+# ifdef _MSC_VER
+# pragma pack(push, 1)
+# endif
+
+struct zzip_version
+{
+ char version[1];
+ char ostype[1];
+} __attribute__((packed));
+
+struct zzip_dostime
+{
+ char time[2];
+ char date[2];
+} __attribute__((packed));
+
+#define ZZIP_CHECKMAGIC(__p,__A,__B,__C,__D) \
+ ( (((char*)(__p))[0]==(__A)) && \
+ (((char*)(__p))[1]==(__B)) && \
+ (((char*)(__p))[2]==(__C)) && \
+ (((char*)(__p))[3]==(__D)) )
+
+/* A. Local file header */
+struct zzip_file_header
+{
+# define ZZIP_FILE_HEADER_MAGIC 0x04034b50
+# define ZZIP_FILE_HEADER_CHECKMAGIC(__p) ZZIP_CHECKMAGIC(__p,'P','K','\3','\4')
+ char z_magic[4]; /* local file header signature (0x04034b50) */
+ struct zzip_version z_extract; /* version needed to extract */
+ char z_flags[2]; /* general purpose bit flag */
+ char z_compr[2]; /* compression method */
+ struct zzip_dostime z_dostime; /* last mod file time (dos format) */
+ char z_crc32[4]; /* crc-32 */
+ char z_csize[4]; /* compressed size */
+ char z_usize[4]; /* uncompressed size */
+ char z_namlen[2]; /* filename length (null if stdin) */
+ char z_extras[2]; /* extra field length */
+ /* followed by filename (of variable size) */
+ /* followed by extra field (of variable size) */
+} __attribute__((packed));
+
+/* B. data descriptor
+ * the data descriptor exists only if bit 3 of z_flags is set. It is byte aligned
+ * and immediately follows the last byte of compressed data. It is only used if
+ * the output media of the compressor was not seekable, eg. standard output.
+ */
+struct zzip_file_trailer
+{
+# define ZZIP_FILE_TRAILER_MAGIC 0x08074B50
+# define ZZIP_FILE_TRAILER_CHECKMAGIC(__p) ZZIP_CHECKMAGIC(__p,'P','K','\7','\8')
+ uint32_t z_magic; /* data descriptor signature (0x08074b50) */
+ uint32_t z_crc32; /* crc-32 */
+ uint32_t z_csize; /* compressed size */
+ uint32_t z_usize; /* uncompressed size */
+} __attribute__((packed));
+
+/* C. central directory structure:
+ [file header] . . . end of central dir record
+*/
+
+/* directory file header
+ * - a single entry including filename, extras and comment may not exceed 64k.
+ */
+
+struct zzip_root_dirent
+{
+# define ZZIP_ROOT_DIRENT_MAGIC 0x02014b50
+# define ZZIP_ROOT_DIRENT_CHECKMAGIC(__p) ZZIP_CHECKMAGIC(__p,'P','K','\1','\2')
+ char z_magic[4]; /* central file header signature (0x02014b50) */
+ struct zzip_version z_encoder; /* version made by */
+ struct zzip_version z_extract; /* version need to extract */
+ char z_flags[2]; /* general purpose bit flag */
+ char z_compr[2]; /* compression method */
+ struct zzip_dostime z_dostime; /* last mod file time&date (dos format) */
+ char z_crc32[4]; /* crc-32 */
+ char z_csize[4]; /* compressed size */
+ char z_usize[4]; /* uncompressed size */
+ char z_namlen[2]; /* filename length (null if stdin) */
+ char z_extras[2]; /* extra field length */
+ char z_comment[2]; /* file comment length */
+ char z_diskstart[2]; /* disk number of start (if spanning zip over multiple disks) */
+ char z_filetype[2]; /* internal file attributes, bit0 = ascii */
+ char z_filemode[4]; /* extrnal file attributes, eg. msdos attrib byte */
+ char z_off[4]; /* relative offset of local file header, seekval if singledisk */
+ /* followed by filename (of variable size) */
+ /* followed by extra field (of variable size) */
+ /* followed by file comment (of variable size) */
+} __attribute__((packed));
+
+/* end of central dir record */
+struct zzip_disk_trailer
+{
+# define ZZIP_DISK_TRAILER_MAGIC 0x06054b50
+# define ZZIP_DISK_TRAILER_CHECKMAGIC(__p) ZZIP_CHECKMAGIC(__p,'P','K','\5','\6')
+ char z_magic[4]; /* end of central dir signature (0x06054b50) */
+ char z_disk[2]; /* number of this disk */
+ char z_finaldisk[2]; /* number of the disk with the start of the central dir */
+ char z_entries[2]; /* total number of entries in the central dir on this disk */
+ char z_finalentries[2]; /* total number of entries in the central dir */
+ char z_rootsize[4]; /* size of the central directory */
+ char z_rootseek[4]; /* offset of start of central directory with respect to *
+ * the starting disk number */
+ char z_comment[2]; /* zipfile comment length */
+ /* followed by zipfile comment (of variable size) */
+} __attribute__((packed));
+
+/* z_flags */
+#define ZZIP_IS_ENCRYPTED(p) ((*(unsigned char*)p)&1)
+#define ZZIP_IS_COMPRLEVEL(p) (((*(unsigned char*)p)>>1)&3)
+#define ZZIP_IS_STREAMED(p) (((*(unsigned char*)p)>>3)&1)
+
+/* z_compr */
+#define ZZIP_IS_STORED 0
+#define ZZIP_IS_SHRUNK 1
+#define ZZIP_IS_REDUCEDx1 2
+#define ZZIP_IS_REDUCEDx2 3
+#define ZZIP_IS_REDUCEDx3 4
+#define ZZIP_IS_REDUCEDx4 5
+#define ZZIP_IS_IMPLODED 6
+#define ZZIP_IS_TOKENIZED 7
+#define ZZIP_IS_DEFLATED 8
+#define ZZIP_IS_DEFLATED_BETTER 9
+#define ZZIP_IS_IMPLODED_BETTER 10
+
+# ifdef _MSC_VER
+# pragma pack(pop)
+# endif
+
+#endif /* _ZZIPFORMAT_H */
+
+
+
+
diff --git a/zzip/info.c b/zzip/info.c
new file mode 100644
index 0000000..144b163
--- /dev/null
+++ b/zzip/info.c
@@ -0,0 +1,161 @@
+/*
+ * Author:
+ * Guido Draheim
+ *
+ * Copyright (c) 2000,2001,2002,2003 Guido Draheim
+ * All rights reserved,
+ * use under the restrictions of the
+ * Lesser GNU General Public License
+ * or alternatively the restrictions
+ * of the Mozilla Public License 1.1
+ */
+
+#include /* exported... */
+#include
+#include
+
+#ifdef ZZIP_HAVE_SYS_STAT_H
+#include
+#else
+#include
+#include
+#endif
+
+/**
+ * just returns dir->errcode of the ZZIP_DIR handle
+ * see: => zzip_dir_open, => zzip_diropen, => zzip_readdir, => zzip_dir_read
+ */
+int
+zzip_error(ZZIP_DIR * dir)
+{
+ return dir->errcode;
+}
+
+/** => zzip_error
+ * This function just does dir->errcode = errcode
+ */
+void
+zzip_seterror(ZZIP_DIR * dir, int errcode)
+{ dir->errcode = errcode; }
+
+/**
+ * This function will just return fp->dir
+ *
+ * If a ZZIP_FILE is contained within a zip-file that one will be a valid
+ * pointer, otherwise a NULL is returned and the ZZIP_FILE wraps a real file.
+ */
+ZZIP_DIR *
+zzip_dirhandle(ZZIP_FILE * fp)
+{
+ return fp->dir;
+}
+
+/** => zzip_dirhandle
+ * This function will just return dir->fd
+ *
+ * If a ZZIP_DIR does point to a zipfile then the file-descriptor of that
+ * zipfile is returned, otherwise a NULL is returned and the ZZIP_DIR wraps
+ * a real directory DIR (if you have dirent on your system).
+ */
+int
+zzip_dirfd(ZZIP_DIR* dir)
+{
+ return dir->fd;
+}
+
+/**
+ * return static const string of the known compression methods,
+ * otherwise just "zipped" is returned
+ */
+zzip_char_t*
+zzip_compr_str(int compr)
+{
+ switch(compr)
+ {
+ case ZZIP_IS_STORED: return "stored";
+ case ZZIP_IS_SHRUNK: return "shrunk";
+ case ZZIP_IS_REDUCEDx1:
+ case ZZIP_IS_REDUCEDx2:
+ case ZZIP_IS_REDUCEDx3:
+ case ZZIP_IS_REDUCEDx4: return "reduced";
+ case ZZIP_IS_IMPLODED: return "imploded";
+ case ZZIP_IS_TOKENIZED: return "tokenized";
+ case ZZIP_IS_DEFLATED: return "deflated";
+ case ZZIP_IS_DEFLATED_BETTER: return "deflatedX";
+ case ZZIP_IS_IMPLODED_BETTER: return "implodedX";
+ default:
+ if (0 < compr && compr < 256) return "zipped";
+ else
+ {
+# ifdef S_ISDIR
+ if (S_ISDIR(compr)) return "directory";
+# endif
+# ifdef S_ISCHR
+ if (S_ISCHR(compr)) return "is/chr";
+# endif
+# ifdef S_ISBLK
+ if (S_ISBLK(compr)) return "is/blk";
+# endif
+# ifdef S_ISFIFO
+ if (S_ISFIFO(compr)) return "is/fifo";
+# endif
+# ifdef S_ISSOCK
+ if (S_ISSOCK(compr)) return "is/sock";
+# endif
+# ifdef S_ISLNK
+ if (S_ISLNK(compr)) return "is/lnk";
+# endif
+ return "special";
+ }
+ }/*switch*/
+}
+
+/** => zzip_file_real
+ * This function checks if the ZZIP_DIR-handle is wrapping
+ * a real directory or a zip-archive.
+ * Returns 1 for a stat'able directory, and 0 for a handle to zip-archive.
+ */
+int
+zzip_dir_real(ZZIP_DIR* dir)
+{
+ return dir->realdir != 0;
+}
+
+/**
+ * This function checks if the ZZIP_FILE-handle is wrapping
+ * a real file or a zip-contained file.
+ * Returns 1 for a stat'able file, and 0 for a file inside a zip-archive.
+ */
+int
+zzip_file_real(ZZIP_FILE* fp)
+{
+ return fp->dir == 0; /* ie. not dependent on a zip-arch-dir */
+}
+
+/** => zzip_file_real
+ * This function returns the posix DIR* handle (if one exists).
+ * Check before with => zzip_dir_real if the
+ * the ZZIP_DIR points to a real directory.
+ */
+void*
+zzip_realdir(ZZIP_DIR* dir)
+{
+ return dir->realdir;
+}
+
+/** => zzip_file_real
+ * This function returns the posix file descriptor (if one exists).
+ * Check before with => zzip_file_real if the
+ * the ZZIP_FILE points to a real file.
+ */
+int
+zzip_realfd(ZZIP_FILE* fp)
+{
+ return fp->fd;
+}
+
+/*
+ * Local variables:
+ * c-file-style: "stroustrup"
+ * End:
+ */
diff --git a/zzip/lib.h b/zzip/lib.h
new file mode 100644
index 0000000..8ff1333
--- /dev/null
+++ b/zzip/lib.h
@@ -0,0 +1,94 @@
+/*
+ * Author:
+ * Guido Draheim
+ * Tomi Ollila
+ *
+ * Copyright (c) 1999,2000,2001,2002,2003 Guido Draheim
+ * All rights reserved
+ * use under the restrictions of the
+ * Lesser GNU General Public License
+ * or alternatively the restrictions
+ * of the Mozilla Public License 1.1
+ *
+ * This is the private header containing definitions that are not
+ * use by a libzzip user application. Writing an extension lib that
+ * uses libzzip will still want to include this. The extension
+ * write should make way to have the ISO C9X integer types defined.
+ */
+#ifndef _ZZIP_LIB_H /* zzip.h */
+#define _ZZIP_LIB_H
+
+#include
+#include
+#include
+
+/*
+ * this structure cannot be wildly enlarged... (see zzip-zip.c)
+ */
+struct zzip_dir_hdr
+{
+ uint32_t d_usize; /* uncompressed size */
+ uint32_t d_csize; /* compressed size */
+ uint32_t d_crc32; /* the adler32-checksum */
+ uint32_t d_off; /* offset of file in zipfile */
+ uint16_t d_reclen; /* next dir_hdr structure offset */
+ uint16_t d_namlen; /* explicit namelen of d_name */
+ uint8_t d_compr; /* the compression type, 0 = store, 8 = inflate */
+ char d_name[1]; /* the actual name of the entry, may contain DIRSEPs */
+};
+#define _ZZIP_DIRENT_HAVE_D_NAMLEN
+#define _ZZIP_DIRENT_HAVE_D_OFF
+#define _ZZIP_DIRENT_HAVE_D_RECLEN
+
+/*
+ * you shall not use this struct anywhere else than in zziplib sources.
+ */
+struct zzip_dir
+{
+ int fd;
+ int errcode; /* zzip_error_t */
+ long refcount;
+ struct {
+ struct zzip_file * fp; /* reduce a lot of alloc/deallocations by */
+ char * buf32k; /* caching one entry of these data structures */
+ } cache;
+ struct zzip_dir_hdr * hdr0; /* zfi; */
+ struct zzip_dir_hdr * hdr; /* zdp; directory pointer, for dirent stuff */
+ struct zzip_file * currentfp; /* last fp used... */
+ struct zzip_dirent dirent;
+ void* realdir; /* e.g. DIR* from posix dirent.h */
+ char* realname;
+ zzip_strings_t* fileext; /* list of fileext to test for */
+ zzip_plugin_io_t io; /* vtable for io routines */
+};
+
+#define ZZIP_32K 32768
+
+/* try to open a zip-basename with default_fileext */
+int __zzip_try_open (zzip_char_t* filename, int filemode,
+ zzip_strings_t* ext, zzip_plugin_io_t io);
+
+ZZIP_DIR *
+zzip_dir_fdopen(int fd, zzip_error_t * errcode_p);
+
+ZZIP_DIR*
+zzip_dir_fdopen_ext_io(int fd, zzip_error_t * errorcode_p,
+ zzip_strings_t* ext, const zzip_plugin_io_t io);
+
+ZZIP_DIR* /*depracated*/
+zzip_dir_alloc_ext_io (zzip_strings_t* ext, const zzip_plugin_io_t io);
+
+/* get 16/32 bits from little-endian zip-file to host byteorder */
+uint32_t __zzip_get32(unsigned char * s);
+uint16_t __zzip_get16(unsigned char * s);
+
+#ifdef __i386__
+#define ZZIP_GET32(x) (*(uint32_t*)(x))
+#define ZZIP_GET16(x) (*(uint16_t*)(x))
+#else
+#define ZZIP_GET32(x) (__zzip_get32(x))
+#define ZZIP_GET16(x) (__zzip_get16(x))
+#endif
+
+#endif /* _ZZIP_H */
+
diff --git a/zzip/stat.c b/zzip/stat.c
new file mode 100644
index 0000000..43b4bfc
--- /dev/null
+++ b/zzip/stat.c
@@ -0,0 +1,76 @@
+/*
+ * Author:
+ * Guido Draheim
+ * Tomi Ollila
+ *
+ * Copyright (c) 1999,2000,2001,2002 Guido Draheim
+ * All rights reserved,
+ * use under the restrictions of the
+ * Lesser GNU General Public License
+ * or alternatively the restrictions
+ * of the Mozilla Public License 1.1
+ *
+ * Description:
+ * although this file is defining a function called zzip_stat it
+ * will not need a real stat(2) exported by the Operating System.
+ * It will just try to fill the fields of the ZZIP_STAT structure
+ * of
+ */
+
+#include /* exported...*/
+#include
+
+/**
+ * obtain information about a filename in an opened zip-archive without
+ * opening that file first. Mostly used to obtain the uncompressed
+ * size of a file inside a zip-archive. see => zzip_dir_open.
+ */
+int
+zzip_dir_stat(ZZIP_DIR * dir, zzip_char_t* name, ZZIP_STAT * zs, int flags)
+{
+ struct zzip_dir_hdr * hdr = dir->hdr0;
+ int (*cmp)(zzip_char_t*, zzip_char_t*);
+
+ cmp = (flags & ZZIP_CASEINSENSITIVE) ? strcasecmp : strcmp;
+
+ if (flags & ZZIP_IGNOREPATH)
+ {
+ char* n = strrchr(name, '/');
+ if (n) name = n + 1;
+ }
+
+ if (hdr)
+ while (1)
+ {
+ register char* hdr_name = hdr->d_name;
+ if (flags & ZZIP_IGNOREPATH)
+ {
+ register char* n = strrchr(hdr_name, '/');
+ if (n) hdr_name = n + 1;
+ }
+
+ if (! cmp(hdr_name, name))
+ break;
+
+ if (! hdr->d_reclen)
+ {
+ dir->errcode = ZZIP_ENOENT;
+ return -1;
+ }
+
+ hdr = (struct zzip_dir_hdr *) ((char *)hdr + hdr->d_reclen);
+ }
+
+ zs->d_compr = hdr->d_compr;
+ zs->d_csize = hdr->d_csize;
+ zs->st_size = hdr->d_usize;
+ zs->d_name = hdr->d_name;
+
+ return 0;
+}
+
+/*
+ * Local variables:
+ * c-file-style: "stroustrup"
+ * End:
+ */
--
2.40.0