# zziplib - 0.13.47

`int` |  | `__zzip_fetch_disk_trailer` |  | `(int fd, zzip_off_t filesize, struct _disk_trailer * _zzip_restrict trailer, zzip_plugin_io_t io)`
`uint32_t` |  | `__zzip_get32` |  | `(unsigned char * s)`
`uint16_t` |  | `__zzip_get16` |  | `(unsigned char * s)`
`uint64_t` |  | `__zzip_get64` |  | `(unsigned char * s)`
`void` |  | `__zzip_set32` |  | `(unsigned char * s, uint32_t v)`
`void` |  | `__zzip_set16` |  | `(unsigned char * s, uint16_t v)`
`void` |  | `__zzip_set64` |  | `(unsigned char * s, uint64_t v)`
`int` |  | `__zzip_parse_root_directory` |  | `(int fd, struct _disk_trailer * trailer, struct zzip_dir_hdr ** hdr_return, zzip_plugin_io_t io)`
`int` |  | `__zzip_try_open` |  | `(zzip_char_t* filename, int filemode, zzip_strings_t* ext, zzip_plugin_io_t io)`
`int` |  | `zzip_closedir` |  | `(ZZIP_DIR* dir)`
`zzip_char_t*` |  | `zzip_compr_str` |  | `(int compr)`
`ZZIP_DIR*` |  | `zzip_createdir` |  | `(zzip_char_t* name, int o_mode)`
`ZZIP_DIR*` |  | `zzip_dir_alloc_ext_io` |  | `(zzip_strings_t* ext, const zzip_plugin_io_t io)`
`ZZIP_DIR*` |  | `zzip_dir_alloc` |  | `(zzip_strings_t* fileext)`
`ZZIP_DIR*` |  | `zzip_dir_creat` |  | `(zzip_char_t* name, int o_mode)`
`ZZIP_DIR*` |  | `zzip_dir_creat_ext_io` |  | `(zzip_char_t* name, int o_mode, 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 * errcode_p, zzip_strings_t* ext, const zzip_plugin_io_t io)`
`int` |  | `zzip_dir_free` |  | `(ZZIP_DIR * dir)`
`int` |  | `zzip_dir_close` |  | `(ZZIP_DIR * dir)`
`ZZIP_DIR*` |  | `zzip_dir_open` |  | `(zzip_char_t* filename, zzip_error_t* e)`
`ZZIP_DIR*` |  | `zzip_dir_open_ext_io` |  | `(zzip_char_t* filename, zzip_error_t* e, zzip_strings_t* ext, zzip_plugin_io_t io)`
`int` |  | `zzip_dir_read` |  | `(ZZIP_DIR * dir, ZZIP_DIRENT * d )`
`int` |  | `zzip_dir_stat` |  | `(ZZIP_DIR * dir, zzip_char_t* name, ZZIP_STAT * zs, int flags)`
`int` |  | `zzip_file_stat` |  | `(ZZIP_FILE* file, ZZIP_STAT* zs)`
`int` |  | `zzip_fstat` |  | `(ZZIP_FILE* file, ZZIP_STAT* zs)`
`ZZIP_DIR *` |  | `zzip_dirhandle` |  | `(ZZIP_FILE * fp)`
`int` |  | `zzip_dirfd` |  | `(ZZIP_DIR* dir)`
`zzip_byte_t*` |  | `zzip_disk_entry_to_data` |  | `(ZZIP_DISK* disk, struct zzip_disk_entry* entry)`
`struct zzip_file_header*` |  | `zzip_disk_entry_to_file_header` |  | `(ZZIP_DISK* disk, struct zzip_disk_entry* entry)`
`zzip__new__ char*` |  | `zzip_disk_entry_strdup_name` |  | `(ZZIP_DISK* disk, struct zzip_disk_entry* entry)`
`zzip__new__ char*` |  | `zzip_disk_entry_strdup_comment` |  | `(ZZIP_DISK* disk, struct zzip_disk_entry* entry)`
`struct zzip_disk_entry*` |  | `zzip_disk_findfile` |  | `(ZZIP_DISK* disk, char* filename, struct zzip_disk_entry* after, zzip_strcmp_fn_t compare)`
`struct zzip_disk_entry*` |  | `zzip_disk_findfirst` |  | `(ZZIP_DISK* disk)`
`struct zzip_disk_entry*` |  | `zzip_disk_findnext` |  | `(ZZIP_DISK* disk, struct zzip_disk_entry* entry)`
`struct zzip_disk_entry*` |  | `zzip_disk_findmatch` |  | `(ZZIP_DISK* disk, char* filespec, struct zzip_disk_entry* after, zzip_fnmatch_fn_t compare, int flags)`
`zzip__new__ ZZIP_DISK_FILE*` |  | `zzip_disk_fopen` |  | `(ZZIP_DISK* disk, char* filename)`
`zzip__new__ ZZIP_DISK_FILE*` |  | `zzip_disk_entry_fopen` |  | `(ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry)`
`zzip_size_t` |  | `zzip_disk_fread` |  | `(void* ptr, zzip_size_t sized, zzip_size_t nmemb, ZZIP_DISK_FILE* file)`
`int` |  | `zzip_disk_fclose` |  | `(ZZIP_DISK_FILE* file)`
`int` |  | `zzip_disk_feof` |  | `(ZZIP_DISK_FILE* file)`
`zzip__new__ ZZIP_DISK*` |  | `zzip_disk_mmap` |  | `(int fd)`
`int` |  | `zzip_disk_init` |  | `(ZZIP_DISK* disk, void* buffer, zzip_size_t buflen)`
`zzip__new__ ZZIP_DISK*` |  | `zzip_disk_new` |  | `(void)`
`int` |  | `zzip_disk_munmap` |  | `(ZZIP_DISK* disk)`
`ZZIP_DISK* zzip__new__` |  | `zzip_disk_open` |  | `(char* filename)`
`int` |  | `zzip_disk_close` |  | `(ZZIP_DISK* disk)`
`zzip_off_t` |  | `zzip_entry_data_offset` |  | `(ZZIP_ENTRY* entry)`
`static zzip_off_t` |  | `zzip_entry_fread_file_header` |  | `(ZZIP_ENTRY* entry, struct zzip_file_header* file_header)`
`zzip__new__ char*` |  | `zzip_entry_strdup_name` |  | `(ZZIP_ENTRY* entry)`
`zzip__new__ ZZIP_ENTRY*` |  | `zzip_entry_findfile` |  | `(FILE* disk, char* filename, ZZIP_ENTRY* _zzip_restrict entry, zzip_strcmp_fn_t compare)`
`zzip__new__ ZZIP_ENTRY*` |  | `zzip_entry_findfirst` |  | `(FILE* disk)`
`zzip__new__ ZZIP_ENTRY*` |  | `zzip_entry_findnext` |  | `(ZZIP_ENTRY* _zzip_restrict entry)`
`int` |  | `zzip_entry_free` |  | `(ZZIP_ENTRY* entry)`
`zzip__new__ ZZIP_ENTRY*` |  | `zzip_entry_findmatch` |  | `(FILE* disk, char* filespec, ZZIP_ENTRY* _zzip_restrict entry, zzip_fnmatch_fn_t compare, int flags)`
`zzip__new__ ZZIP_ENTRY_FILE*` |  | `zzip_entry_fopen` |  | `(ZZIP_ENTRY* entry, int takeover)`
`zzip__new__ ZZIP_ENTRY_FILE*` |  | `zzip_entry_ffile` |  | `(FILE* disk, char* filename)`
`zzip_size_t` |  | `zzip_entry_fread` |  | `(void* ptr, zzip_size_t sized, zzip_size_t nmemb, ZZIP_ENTRY_FILE* file)`
`int` |  | `zzip_entry_fclose` |  | `(ZZIP_ENTRY_FILE* file)`
`int` |  | `zzip_entry_feof` |  | `(ZZIP_ENTRY_FILE* file)`
`int` |  | `zzip_errno` |  | `(int errcode)`
`int` |  | `zzip_error` |  | `(ZZIP_DIR * dir)`
`void` |  | `zzip_seterror` |  | `(ZZIP_DIR * dir, int errcode)`
`int` |  | `zzip_fclose` |  | `(ZZIP_FILE * fp)`
`int` |  | `zzip_close` |  | `(ZZIP_FILE* fp)`
`int` |  | `zzip_file_close` |  | `(ZZIP_FILE * fp)`
`ZZIP_FILE*` |  | `zzip_file_creat` |  | `(ZZIP_DIR* dir, zzip_char_t* name, int o_mode)`
`int` |  | `zzip_file_mkdir` |  | `(ZZIP_DIR* dir, zzip_char_t* name, int o_mode)`
`ZZIP_FILE *` |  | `zzip_file_open` |  | `(ZZIP_DIR * dir, zzip_char_t* name, int o_mode)`
`zzip_ssize_t` |  | `zzip_file_read` |  | `(ZZIP_FILE * fp, char * buf, zzip_size_t len)`
`int` |  | `zzip_file_real` |  | `(ZZIP_FILE* fp)`
`int` |  | `zzip_dir_real` |  | `(ZZIP_DIR* dir)`
`void*` |  | `zzip_realdir` |  | `(ZZIP_DIR* dir)`
`int` |  | `zzip_realfd` |  | `(ZZIP_FILE* fp)`
`ZZIP_FILE*` |  | `zzip_fopen` |  | `(zzip_char_t* filename, zzip_char_t* mode)`
`ZZIP_FILE*` |  | `zzip_freopen` |  | `(zzip_char_t* filename, zzip_char_t* mode, ZZIP_FILE* stream)`
`static int` |  | `zzip_inflate_init` |  | `(ZZIP_FILE * fp, struct zzip_dir_hdr* hdr)`
`int` |  | `zzip_init_io` |  | `(zzip_plugin_io_handlers_t io, int flags)`
`zzip_plugin_io_t` |  | `zzip_get_default_io` |  | `()`
`zzip__new__ ZZIP_MEM_DISK*` |  | `zzip_mem_disk_fdopen` |  | `(int fd)`
`long` |  | `zzip_mem_disk_load` |  | `(ZZIP_MEM_DISK* dir, ZZIP_DISK* disk)`
`zzip__new__ ZZIP_MEM_DISK*` |  | `zzip_mem_disk_open` |  | `(char* filename)`
`zzip__new__ ZZIP_MEM_ENTRY*` |  | `zzip_mem_entry_new` |  | `(ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry)`
`int inline` |  | `zzip_mkdir` |  | `(zzip_char_t* name, int o_mode)`
`ZZIP_FILE* inline` |  | `zzip_creat` |  | `(zzip_char_t* name, int o_mode)`
`void inline` |  | `zzip_mkfifo` |  | `(zzip_char_t* name, int o_mode)`
`void inline` |  | `zzip_sync` |  | `(void)`
`ZZIP_FILE*` |  | `zzip_open` |  | `(zzip_char_t* filename, int o_flags)`
`ZZIP_FILE*` |  | `zzip_open_ext_io` |  | `(zzip_char_t* filename, int o_flags, int o_modes, zzip_strings_t* ext, zzip_plugin_io_t io)`
`ZZIP_FILE*` |  | `zzip_open_shared_io` |  | `(ZZIP_FILE* stream, zzip_char_t* filename, int o_flags, int o_modes, zzip_strings_t* ext, zzip_plugin_io_t io)`
`ZZIP_DIR*` |  | `zzip_opendir` |  | `(zzip_char_t* filename)`
`ZZIP_DIR*` |  | `zzip_opendir_ext_io` |  | `(zzip_char_t* filename, int o_modes, zzip_strings_t* ext, zzip_plugin_io_t io)`
`zzip_ssize_t` |  | `zzip_read` |  | `(ZZIP_FILE * fp, char * buf, zzip_size_t len)`
`zzip_size_t` |  | `zzip_fread` |  | `(void *ptr, zzip_size_t size, zzip_size_t nmemb, ZZIP_FILE *file)`
`ZZIP_DIRENT*` |  | `zzip_readdir` |  | `(ZZIP_DIR * dir)`
`int` |  | `zzip_rewind` |  | `(ZZIP_FILE *fp)`
`void` |  | `zzip_rewinddir` |  | `(ZZIP_DIR * dir)`
`zzip_off_t` |  | `zzip_telldir` |  | `(ZZIP_DIR* dir)`
`void` |  | `zzip_seekdir` |  | `(ZZIP_DIR* dir, zzip_off_t offset)`
`zzip_off_t` |  | `zzip_seek` |  | `(ZZIP_FILE * fp, zzip_off_t offset, int whence)`
`zzip_char_t*` |  | `zzip_strerror` |  | `(int errcode)`
`zzip_char_t*` |  | `zzip_strerror_of` |  | `(ZZIP_DIR* dir)`
`zzip_off_t` |  | `zzip_tell` |  | `(ZZIP_FILE * fp)`
`zzip_ssize_t` |  | `zzip_write` |  | `(ZZIP_FILE* file, const void* ptr, zzip_size_t len)`
`zzip_ssize_t` |  | `zzip_file_write` |  | `(ZZIP_FILE* file, const void* ptr, zzip_size_t len)`
`zzip_size_t` |  | `zzip_fwrite` |  | `(const void* ptr, zzip_size_t len, zzip_size_t multiply, ZZIP_FILE* file)`

### Documentation

`int`
`__zzip_fetch_disk_trailer` ``(int fd, zzip_off_t filesize, struct _disk_trailer * _zzip_restrict trailer, zzip_plugin_io_t io)``
  <para> (zzip/zip.c) </para>

  <function>The __zzip_fetch_disk_trailer function</function> is used by `zzip_file_open`. It tries to find
  the zip's central directory info that is usually a few
  bytes off the end of the file.

  (../../zzip/zip.c)

`uint32_t`
`__zzip_get32` ``(unsigned char * s)``
`uint16_t`
`__zzip_get16` ``(unsigned char * s)``
`uint64_t`
`__zzip_get64` ``(unsigned char * s)``
`void`
`__zzip_set32` ``(unsigned char * s, uint32_t v)``
`void`
`__zzip_set16` ``(unsigned char * s, uint16_t v)``
`void`
`__zzip_set64` ``(unsigned char * s, uint64_t v)``
  <para> (zzip/fetch.c) </para>

  Make 32 bit value in host byteorder from little-endian mapped octet-data
  (works also on machines which SIGBUS on misaligned data access (eg. 68000))

  <function>The __zzip_get16 function</function> does the same for a 16 bit value.

  <function>The __zzip_get64 function</function> does the same for an off64_t value.

  <function>The __zzip_set32 function</function> pushes a 32bit value at the specified address

  <function>The __zzip_set16 function</function> does the same for a 16 bit value.

  <function>The __zzip_set64 function</function> pushes a off64_t value at the specified address

  (../../zzip/fetch.c)

`int`
`__zzip_parse_root_directory` ``(int fd, struct _disk_trailer * trailer, struct zzip_dir_hdr ** hdr_return, zzip_plugin_io_t io)``
  <para> (zzip/zip.c) </para>

  <function>The __zzip_parse_root_directory function</function> is used by `zzip_file_open`, it is usually called after
  `__zzip_find_disk_trailer`. It will parse the zip's central directory
  information and create a zziplib private directory table in
  memory.

  (../../zzip/zip.c)

`int`
`__zzip_try_open` ``(zzip_char_t* filename, int filemode, zzip_strings_t* ext, zzip_plugin_io_t io)``
  <para> (zzip/zip.c) </para>

  will attach a .zip extension and tries to open it
  the with `open`(2). This is a helper function for
  `zzip_dir_open`, `zzip_opendir` and `zzip_open`.

  (../../zzip/zip.c)

`int`
`zzip_closedir` ``(ZZIP_DIR* dir)``
  <para> (zzip/dir.c) </para>

  <function>The zzip_closedir function</function> is the equivalent of `closedir`(3) for a realdir or zipfile.

  <function>The zzip_closedir function</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.

  (../../zzip/dir.c)

`zzip_char_t*`
`zzip_compr_str` ``(int compr)``
  <para> (zzip/info.c) </para>

  return static const string of the known compression methods,
  otherwise just "zipped" is returned

  (../../zzip/info.c)

`ZZIP_DIR*`
`zzip_createdir` ``(zzip_char_t* name, int o_mode)``
  <para> create a new archive area for writing </para>

  <function>The zzip_createdir function</function> will create a new archive area. This may either be a
  a new zip archive or a new directory in the filesystem. The returned
  parameter is a new "zzip dir" handle that should be saved to a variable
  so it can be used a base argument for `zzip_file_mkdir` and
  `zzip_file_creat` calls. The returned handle wraps both possibilities,
  it can be representing a zip central directory that must be
  saved to disk using `zzip_closedir` or it is just a handle for the
  name of the real directory that still must be run through
  `zzip_closedir` to release the wrapper around the directory name.

  The magic is pushed through the o_mode argument. Using a mode that
  has no group-write bit set (S_IWGRP = 0040) then the file is
  created as a zip directory. Note that this is unabridged of any
  umask value in the system where the argument to <function>the zzip_createdir function</function> could
  be 0775 but with an umask of 0755 it turns out as 0755 for a real
  directory. Using 0755 directly would not create it as a real directory
  but as a zip archive handle.

  <function>The zzip_createdir function</function> is not yet implemented, check for #def ZZIP_NO_CREAT
  Write-support will extend `zzip_closedir` with semantics to finalize the
  zip-archive by writing the zip-trailer and closing the archive file.

  Returns null on error and sets errno. Remember, according to posix
  the `creat`(2) call is equivalent to

        open (path, O_WRONLY | O_CREAT | O_TRUNC, o_mode)

  so any previous zip-archive will be overwritten unconditionally and
  EEXIST errors from `mkdir`(2) are suppressed. (fixme: delete the
  given subtree? like suggested by O_TRUNC? not done so far!)

  (../../zzip/write.c)

`ZZIP_DIR*`
`zzip_dir_alloc_ext_io` ``(zzip_strings_t* ext, const zzip_plugin_io_t io)``
`ZZIP_DIR*`
`zzip_dir_alloc` ``(zzip_strings_t* fileext)``
  <para> (zzip/zip.c) </para>

  allocate a new ZZIP_DIR handle and do basic
  initializations before usage by `zzip_dir_fdopen`
  `zzip_dir_open` `zzip_file_open` or through
  `zzip_open`
  (ext==null flags uses { ".zip" , ".ZIP" } )
  (io ==null flags use of posix io defaults)

  <function>the zzip_dir_alloc function</function> is obsolete - it was generally used for implementation
  and exported to let other code build on it. It is now advised to
  use `zzip_dir_alloc_ext_io` now on explicitly, just set that second
  argument to zero to achieve the same functionality as the old style.

  (../../zzip/zip.c)

`ZZIP_DIR*`
`zzip_dir_creat` ``(zzip_char_t* name, int o_mode)``
`ZZIP_DIR*`
`zzip_dir_creat_ext_io` ``(zzip_char_t* name, int o_mode, zzip_strings_t* ext, zzip_plugin_io_t io)``
  <para> create a new zip archive for writing </para>

  <function>The zzip_dir_creat function</function> will create a new zip archive. The returned parameter
  is a new "zzip dir" handle that should be saved to a variable so it
  can be used a base argument for `zzip_mkdir` and `zzip_creat` calls.
  The returned handle represents a zip central directory that must be
  saved to disk using `zzip_closedir`.

  Returns null on error and sets errno. Remember, according to posix
  the `creat`(2) call is equivalent to

        open (path, O_WRONLY | O_CREAT | O_TRUNC, o_mode)

  so any previous zip-archive will be overwritten unconditionally and
  EEXIST errors from `mkdir`(2) are suppressed. (fixme: delete the
  given subtree? like suggested by O_TRUNC? not done so far!)

  If the third argument "ext" has another special meaning here, as it
  is used to ensure that a given zip-file is created with the first entry
  of the ext-list appended as an extension unless the file-path already
  ends with a file-extension registered in the list. Therefore {"",0}
  matches all files and creates them as zip-archives under the given
  nonmodified name. (Some magic here? If the path ends in the path
  separator then make a real directory even in the presence of ext-list?)

  <function>The zzip_dir_creat_ext_io function</function> is not yet implemented, check for #def ZZIP_NO_CREAT
  Write-support will extend `zzip_closedir` with semantics to finalize the
  zip-archive by writing the zip-trailer and closing the archive file.

  (../../zzip/write.c)

`ZZIP_DIR *`
`zzip_dir_fdopen` ``(int fd, zzip_error_t * errcode_p)``
`ZZIP_DIR *`
`zzip_dir_fdopen_ext_io` ``(int fd, zzip_error_t * errcode_p, zzip_strings_t* ext, const zzip_plugin_io_t io)``
  <para> (zzip/zip.c) </para>

  used by the `zzip_dir_open` and zzip_opendir(2) call. Opens the
  zip-archive as specified with the fd which points to an
  already openend file. <function>The zzip_dir_fdopen function</function> then search and parse
  the zip's central directory.

  NOTE: refcount is zero, so an _open/_close pair will also delete
  this _dirhandle

  <function>the zzip_dir_fdopen_ext_io function</function> uses explicit ext and io instead of the internal
  defaults, setting these to zero is equivalent to `zzip_dir_fdopen`

  (../../zzip/zip.c)

`int`
`zzip_dir_free` ``(ZZIP_DIR * dir)``
`int`
`zzip_dir_close` ``(ZZIP_DIR * dir)``
  <para> (zzip/zip.c) </para>

  will free the zzip_dir handle unless there are still
  zzip_files attached (that may use its cache buffer).
  This is the inverse of `zzip_dir_alloc` , and both
  are helper functions used implicitly in other zzipcalls
  e.g. `zzip_dir_close` = zzip_close

  returns zero on sucess
  returns the refcount when files are attached.

  `zzip_dir_close` -
  It will also `free`(2) the `ZZIP_DIR`-handle given.
  the counterpart for `zzip_dir_open`
  see also `zzip_dir_free`

  (../../zzip/zip.c)

`ZZIP_DIR*`
`zzip_dir_open` ``(zzip_char_t* filename, zzip_error_t* e)``
`ZZIP_DIR*`
`zzip_dir_open_ext_io` ``(zzip_char_t* filename, zzip_error_t* e, zzip_strings_t* ext, zzip_plugin_io_t io)``
`int`
`zzip_dir_read` ``(ZZIP_DIR * dir, ZZIP_DIRENT * d )``
  <para> (zzip/zip.c) </para>

  Opens the zip-archive (if available).
  the two ext_io arguments will default to use posix io and
  a set of default fileext that can atleast add .zip ext itself.

  <function>the zzip_dir_open_ext_io function</function> uses explicit ext and io instead of the internal
  defaults. Setting these to zero is equivalent to `zzip_dir_open`

  `zzip_dir_read` -
  fills the dirent-argument with the values and
  increments the read-pointer of the dir-argument.

  returns 0 if there no entry (anymore).

  (../../zzip/zip.c)

`int`
`zzip_dir_stat` ``(ZZIP_DIR * dir, zzip_char_t* name, ZZIP_STAT * zs, int flags)``
`int`
`zzip_file_stat` ``(ZZIP_FILE* file, ZZIP_STAT* zs)``
`int`
`zzip_fstat` ``(ZZIP_FILE* file, ZZIP_STAT* zs)``
  <para> (zzip/stat.c) </para>

  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`.

  <function>The zzip_file_stat function</function> will obtain information about a opened file _within_ a
  zip-archive. The file is supposed to be open (otherwise -1 is returned).
  The st_size stat-member contains the uncompressed size. The optional
  d_name is never set here.

  <function>The zzip_fstat function</function> will obtain information about a opened file which may be
  either real/zipped. The file is supposed to be open (otherwise -1 is
  returned). The st_size stat-member contains the uncompressed size.
  The optional d_name is never set here. For a real file, we do set the
  d_csize := st_size and d_compr := 0 for meaningful defaults.

  (../../zzip/stat.c)

`ZZIP_DIR *`
`zzip_dirhandle` ``(ZZIP_FILE * fp)``
`int`
`zzip_dirfd` ``(ZZIP_DIR* dir)``
  <para> (zzip/info.c) </para>

  <function>The zzip_dirhandle function</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.

  <function>The zzip_dirfd function</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).

  (../../zzip/info.c)

`zzip_byte_t*`
`zzip_disk_entry_to_data` ``(ZZIP_DISK* disk, struct zzip_disk_entry* entry)``
`struct zzip_file_header*`
`zzip_disk_entry_to_file_header` ``(ZZIP_DISK* disk, struct zzip_disk_entry* entry)``
`zzip__new__ char*`
`zzip_disk_entry_strdup_name` ``(ZZIP_DISK* disk, struct zzip_disk_entry* entry)``
`zzip__new__ char*`
`zzip_disk_entry_strdup_comment` ``(ZZIP_DISK* disk, struct zzip_disk_entry* entry)``
  <para> helper functions for (mmapped) zip access api </para>

  <function>The zzip_disk_entry_to_data function</function> augments the other zzip_disk_entry_* helpers: here we move
  a disk_entry pointer (as returned by _find* functions) into a pointer to
  the data block right after the file_header. Only disk->buffer would be
  needed to perform the seek but we check the mmapped range end as well.

  <function>The zzip_disk_entry_to_file_header function</function> does half the job of `zzip_disk_entry_to_data` where it
  can augment with `zzip_file_header_to_data` helper from format/fetch.h

  <function>The zzip_disk_entry_strdup_name function</function> is a big helper despite its little name: in a zip file the
  encoded filenames are usually NOT zero-terminated but for common usage
  with libc we need it that way. Secondly, the filename SHOULD be present
  in the zip central directory but if not then we fallback to the filename
  given in the file_header of each compressed data portion.

  <function>The zzip_disk_entry_strdup_comment function</function> is similar creating a reference to a zero terminated
  string but it can only exist in the zip central directory entry.

  (../../zzip/mmapped.c)

`struct zzip_disk_entry*`
`zzip_disk_findfile` ``(ZZIP_DISK* disk, char* filename, struct zzip_disk_entry* after, zzip_strcmp_fn_t compare)``
`struct zzip_disk_entry*`
`zzip_disk_findfirst` ``(ZZIP_DISK* disk)``
`struct zzip_disk_entry*`
`zzip_disk_findnext` ``(ZZIP_DISK* disk, struct zzip_disk_entry* entry)``
`struct zzip_disk_entry*`
`zzip_disk_findmatch` ``(ZZIP_DISK* disk, char* filespec, struct zzip_disk_entry* after, zzip_fnmatch_fn_t compare, int flags)``
  <para> search for files in the (mmapped) zip central directory </para>

  <function>The zzip_disk_findfile function</function> is given a filename as an additional argument, to find the
  disk_entry matching a given filename. The compare-function is usually
  strcmp or strcasecmp or perhaps strcoll, if null then strcmp is used.
  - use null as argument for "after"-entry when searching the first
  matching entry, otherwise the last returned value if you look for other
  entries with a special "compare" function (if null then a doubled search
  is rather useless with this variant of _findfile).

  <function>The zzip_disk_findfirst function</function> is the first call of all the zip access functions here.
  It contains the code to find the first entry of the zip central directory.
  Here we require the mmapped block to represent a real zip file where the
  disk_trailer is _last_ in the file area, so that its position would be at
  a fixed offset from the end of the file area if not for the comment field
  allowed to be of variable length (which needs us to do a little search
  for the disk_tailer). However, in this simple implementation we disregard
  any disk_trailer info telling about multidisk archives, so we just return
  a pointer to the zip central directory.

  For an actual means, we are going to search backwards from the end
  of the mmaped block looking for the PK-magic signature of a
  disk_trailer. If we see one then we check the rootseek value to
  find the first disk_entry of the root central directory. If we find
  the correct PK-magic signature of a disk_entry over there then we
  assume we are done and we are going to return a pointer to that label.

  The return value is a pointer to the first zzip_disk_entry being checked
  to be within the bounds of the file area specified by the arguments. If
  no disk_trailer was found then null is returned, and likewise we only
  accept a disk_trailer with a seekvalue that points to a disk_entry and
  both parts have valid PK-magic parts. Beyond some sanity check we try to
  catch a common brokeness with zip archives that still allows us to find
  the start of the zip central directory.

  <function>The zzip_disk_findnext function</function> takes an existing disk_entry in the central root directory
  (e.g. from zzip_disk_findfirst) and returns the next entry within in
  the given bounds of the mmapped file area.

  <function>The zzip_disk_findmatch function</function> uses a compare-function with an additional argument
  and it is called just like fnmatch(3) from POSIX.2 AD:1993), i.e.
  the argument filespec first and the ziplocal filename second with
  the integer-flags put in as third to the indirect call. If the
  platform has fnmatch available then null-compare will use that one
  and otherwise we fall back to mere strcmp, so if you need fnmatch
  searching then please provide an implementation somewhere else.
  - use null as argument for "after"-entry when searching the first
  matching entry, or the last disk_entry return-value to find the
  next entry matching the given filespec.

  (../../zzip/mmapped.c)

`zzip__new__ ZZIP_DISK_FILE*`
`zzip_disk_fopen` ``(ZZIP_DISK* disk, char* filename)``
`zzip__new__ ZZIP_DISK_FILE*`
`zzip_disk_entry_fopen` ``(ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry)``
`zzip_size_t`
`zzip_disk_fread` ``(void* ptr, zzip_size_t sized, zzip_size_t nmemb, ZZIP_DISK_FILE* file)``
`int`
`zzip_disk_fclose` ``(ZZIP_DISK_FILE* file)``
`int`
`zzip_disk_feof` ``(ZZIP_DISK_FILE* file)``
  <para> openening a file part wrapped within a (mmapped) zip archive </para>

  <function>The zzip_disk_fopen function</function> opens a file found by name, so it does a search into
  the zip central directory with `zzip_disk_findfile` and whatever
  is found first is given to `zzip_disk_entry_fopen`

  the ZZIP_DISK_FILE* is rather simple in just encapsulating the
  arguments given to <function>the zzip_disk_entry_fopen function</function> plus a zlib deflate buffer.
  Note that the ZZIP_DISK pointer does already contain the full
  mmapped file area of a zip disk, so open()ing a file part within
  that area happens to be a lookup of its bounds and encoding. That
  information is memorized on the ZZIP_DISK_FILE so that subsequent
  _read() operations will be able to get the next data portion or
  return an eof condition for that file part wrapped in the zip archive.

  <function>The zzip_disk_fread function</function> reads more bytes into the output buffer specified as
  arguments. The return value is null on eof or error, the stdio-like
  interface can not distinguish between these so you need to check
  with `zzip_disk_feof` for the difference.

  <function>The zzip_disk_fclose function</function> releases any zlib decoder info needed for decompression
  and dumps the ZZIP_DISK_FILE* then.

  <function>The zzip_disk_feof function</function> allows to distinguish an error from an eof condition.
  Actually, if we found an error but we did already reach eof then we
  just keep on saying that it was an eof, so the app can just continue.

  (../../zzip/mmapped.c)

`zzip__new__ ZZIP_DISK*`
`zzip_disk_mmap` ``(int fd)``
`int`
`zzip_disk_init` ``(ZZIP_DISK* disk, void* buffer, zzip_size_t buflen)``
`zzip__new__ ZZIP_DISK*`
`zzip_disk_new` ``(void)``
`int`
`zzip_disk_munmap` ``(ZZIP_DISK* disk)``
`ZZIP_DISK* zzip__new__`
`zzip_disk_open` ``(char* filename)``
`int`
`zzip_disk_close` ``(ZZIP_DISK* disk)``
  <para> turn a filehandle into a mmapped zip disk archive handle </para>

  <function>The zzip_disk_mmap function</function> uses the given file-descriptor to detect the length of the
  file and calls the system `mmap`(2) to put it in main memory. If it is
  successful then a newly allocated ZZIP_DISK* is returned with
  disk->buffer pointing to the mapview of the zipdisk content.

  <function>The zzip_disk_init function</function> does primary initialization of a disk-buffer struct.

  <function>The zzip_disk_new function</function> allocates a new disk-buffer with `malloc`(3)

  <function>The zzip_disk_munmap function</function> is the inverse of `zzip_disk_mmap` and using the system
  munmap(2) on the buffer area and `free`(3) on the ZZIP_DISK structure.

  <function>The zzip_disk_open function</function> opens the given archive by name and turn the filehandle
  to `zzip_disk_mmap` for bringing it to main memory. If it can not
  be `mmap`(2)'ed then we slurp the whole file into a newly `malloc`(2)'ed
  memory block. Only if that fails too then we return null. Since handling
  of disk->buffer is ambigous it should not be snatched away please.

  <function>The zzip_disk_close function</function> will release all data needed to access a (mmapped)
  zip archive, including any malloc()ed blocks, sharedmem mappings
  and it dumps the handle struct as well.

  (../../zzip/mmapped.c)

`zzip_off_t`
`zzip_entry_data_offset` ``(ZZIP_ENTRY* entry)``
`static zzip_off_t`
`zzip_entry_fread_file_header` ``(ZZIP_ENTRY* entry, struct zzip_file_header* file_header)``
`zzip__new__ char*`
`zzip_entry_strdup_name` ``(ZZIP_ENTRY* entry)``
  <para> helper functions for (fseeko) zip access api </para>

  <function>The zzip_entry_data_offset function</function>s returns the seekval offset of the data portion of the
  file referenced by the given zzip_entry. It requires an intermediate
  check of the file_header structure (i.e. it reads it from disk). After
  this call, the contained diskfile readposition is already set to the
  data_offset returned here. On error -1 is returned.

  <function>The zzip_entry_fread_file_header function</function>s read the correspoding struct zzip_file_header from
  the zip disk of the given "entry". The returned off_t points to the
  end of the file_header where the current fseek pointer has stopped.
  This is used to immediatly parse out any filename/extras block following
  the file_header. The return value is null on error.

  <function>The zzip_entry_strdup_name function</function> is a big helper despite its little name: in a zip file the
  encoded filenames are usually NOT zero-terminated but for common usage
  with libc we need it that way. Secondly, the filename SHOULD be present
  in the zip central directory but if not then we fallback to the filename
  given in the file_header of each compressed data portion.

  (../../zzip/fseeko.c)

`zzip__new__ ZZIP_ENTRY*`
`zzip_entry_findfile` ``(FILE* disk, char* filename, ZZIP_ENTRY* _zzip_restrict entry, zzip_strcmp_fn_t compare)``
`zzip__new__ ZZIP_ENTRY*`
`zzip_entry_findfirst` ``(FILE* disk)``
`zzip__new__ ZZIP_ENTRY*`
`zzip_entry_findnext` ``(ZZIP_ENTRY* _zzip_restrict entry)``
`int`
`zzip_entry_free` ``(ZZIP_ENTRY* entry)``
`zzip__new__ ZZIP_ENTRY*`
`zzip_entry_findmatch` ``(FILE* disk, char* filespec, ZZIP_ENTRY* _zzip_restrict entry, zzip_fnmatch_fn_t compare, int flags)``
  <para> search for files in the (fseeko) zip central directory </para>

  <function>The zzip_entry_findfile function</function> is given a filename as an additional argument, to find the
  disk_entry matching a given filename. The compare-function is usually
  strcmp or strcasecmp or perhaps strcoll, if null then strcmp is used.
  - use null as argument for "old"-entry when searching the first
  matching entry, otherwise the last returned value if you look for other
  entries with a special "compare" function (if null then a doubled search
  is rather useless with this variant of _findfile). If no further entry is
  found then null is returned and any "old"-entry gets already free()d.

  <function>The zzip_entry_findfirst function</function> is the first call of all the zip access functions here.
  It contains the code to find the first entry of the zip central directory.
  Here we require the stdio handle to represent a real zip file where the
  disk_trailer is _last_ in the file area, so that its position would be at
  a fixed offset from the end of the file area if not for the comment field
  allowed to be of variable length (which needs us to do a little search
  for the disk_tailer). However, in this simple implementation we disregard
  any disk_trailer info telling about multidisk archives, so we just return
  a pointer to the first entry in the zip central directory of that file.

  For an actual means, we are going to search backwards from the end
  of the mmaped block looking for the PK-magic signature of a
  disk_trailer. If we see one then we check the rootseek value to
  find the first disk_entry of the root central directory. If we find
  the correct PK-magic signature of a disk_entry over there then we
  assume we are done and we are going to return a pointer to that label.

  The return value is a pointer to the first zzip_disk_entry being checked
  to be within the bounds of the file area specified by the arguments. If
  no disk_trailer was found then null is returned, and likewise we only
  accept a disk_trailer with a seekvalue that points to a disk_entry and
  both parts have valid PK-magic parts. Beyond some sanity check we try to
  catch a common brokeness with zip archives that still allows us to find
  the start of the zip central directory.

  <function>The zzip_entry_findnext function</function> takes an existing "entry" in the central root directory
  (e.g. from zzip_entry_findfirst) and moves it to point to the next entry.
  On error it returns 0, otherwise the old entry. If no further match is
  found then null is returned and the entry already free()d. If you want
  to stop searching for matches before that case then please call
  `zzip_entry_free` on the cursor struct ZZIP_ENTRY.

  <function>the zzip_entry_free function</function> releases the malloc()ed areas needed for zzip_entry, the
  pointer is invalid afterwards. <function>The zzip_entry_free function</function> has #define synonyms of
  zzip_entry_findlast(), zzip_entry_findlastfile(), zzip_entry_findlastmatch()

  <function>The zzip_entry_findmatch function</function> uses a compare-function with an additional argument
  and it is called just like fnmatch(3) from POSIX.2 AD:1993), i.e.
  the argument filespec first and the ziplocal filename second with
  the integer-flags put in as third to the indirect call. If the
  platform has fnmatch available then null-compare will use that one
  and otherwise we fall back to mere strcmp, so if you need fnmatch
  searching then please provide an implementation somewhere else.
  - use null as argument for "after"-entry when searching the first
  matching entry, or the last disk_entry return-value to find the
  next entry matching the given filespec. If no further entry is
  found then null is returned and any "old"-entry gets already free()d.

  (../../zzip/fseeko.c)

`zzip__new__ ZZIP_ENTRY_FILE*`
`zzip_entry_fopen` ``(ZZIP_ENTRY* entry, int takeover)``
`zzip__new__ ZZIP_ENTRY_FILE*`
`zzip_entry_ffile` ``(FILE* disk, char* filename)``
`zzip_size_t`
`zzip_entry_fread` ``(void* ptr, zzip_size_t sized, zzip_size_t nmemb, ZZIP_ENTRY_FILE* file)``
`int`
`zzip_entry_fclose` ``(ZZIP_ENTRY_FILE* file)``
`int`
`zzip_entry_feof` ``(ZZIP_ENTRY_FILE* file)``
  <para> open a file within a zip disk for reading </para>

  <function>The zzip_entry_fopen function</function> does take an "entry" argument and copies it (or just takes
  it over as owner) to a new ZZIP_ENTRY_FILE handle structure. That
  structure contains also a zlib buffer for decoding. <function>The zzip_entry_fopen function</function> does
  seek to the file_header of the given "entry" and validates it for the
  data buffer following it. We do also prefetch some data from the data
  buffer thereby trying to match the disk pagesize for faster access later.
  The `zzip_entry_fread` will then read in chunks of pagesizes which is
  the size of the internal readahead buffer. If an error occurs then null
  is returned.

  <function>The zzip_entry_ffile function</function> opens a file found by name, so it does a search into
  the zip central directory with `zzip_entry_findfile` and whatever
  is found first is given to `zzip_entry_fopen`

  <function>The zzip_entry_fread function</function> reads more bytes into the output buffer specified as
  arguments. The return value is null on eof or error, the stdio-like
  interface can not distinguish between these so you need to check
  with `zzip_entry_feof` for the difference.

  <function>The zzip_entry_fclose function</function> releases any zlib decoder info needed for decompression
  and dumps the ZZIP_ENTRY_FILE struct then.

  <function>The zzip_entry_feof function</function> allows to distinguish an error from an eof condition.
  Actually, if we found an error but we did already reach eof then we
  just keep on saying that it was an eof, so the app can just continue.

  (../../zzip/fseeko.c)

`int`
`zzip_errno` ``(int errcode)``
  <para> (zzip/err.c) </para>

  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.

  (../../zzip/err.c)

`int`
`zzip_error` ``(ZZIP_DIR * dir)``
`void`
`zzip_seterror` ``(ZZIP_DIR * dir, int errcode)``
  <para> (zzip/info.c) </para>

  just returns dir->errcode of the ZZIP_DIR handle
  see: `zzip_dir_open`, `zzip_diropen`, `zzip_readdir`, `zzip_dir_read`

  <function>The zzip_seterror function</function> just does dir->errcode = errcode

  (../../zzip/info.c)

`int`
`zzip_fclose` ``(ZZIP_FILE * fp)``
`int`
`zzip_close` ``(ZZIP_FILE* fp)``
  <para> (zzip/file.c) </para>

  <function>The zzip_fclose function</function> closes the given ZZIP_FILE handle.

  If the ZZIP_FILE wraps a normal stat'fd then it is just that int'fd
  that is being closed and the otherwise empty ZZIP_FILE gets freed.

  `zzip_close` -

  (../../zzip/file.c)

`int`
`zzip_file_close` ``(ZZIP_FILE * fp)``
  <para> (zzip/file.c) </para>

  the direct function of `zzip_close`(fp). it will cleanup the
  inflate-portion of `zlib` and free the structure given.

  it is called quite from the error-cleanup parts
  of the various `_open` functions.

  the .refcount is decreased and if zero the fp->dir is closed just as well.

  (../../zzip/file.c)

`ZZIP_FILE*`
`zzip_file_creat` ``(ZZIP_DIR* dir, zzip_char_t* name, int o_mode)``
`int`
`zzip_file_mkdir` ``(ZZIP_DIR* dir, zzip_char_t* name, int o_mode)``
  <para> start next file entry in a zip archive </para>

  <function>The zzip_file_creat function</function> will create a new file within a zzip archive, the
  one given as the primary argument and additionally to the posix
  creat(2) - just like zzip_mkdir has an additional argument over
  the posix mkdir(2) spec. For <function>the zzip_file_creat function</function> the primary parameter
  can be null as well thereby creating a real file instead of a new
  one inside the zip-archive otherwise given. If the primary parameter is
  not null but wraps a real directory then all new files are also real.

  <function>The zzip_file_creat function</function> is not yet implemented, check for #def ZZIP_NO_CREAT

  Returns NULL on an error setting errno, and opening a file _within_
  a zip archive using O_RDONLY (and similar stuff) will surely lead to
  an error.

  <function>The zzip_file_mkdir function</function> has an additional primary argument over the posix
  mkdir(2) - if it is null then <function>the zzip_file_mkdir function</function> behaves just like
  posix mkdir(2). The zzip_dir argument can be set to the result
  of a `zzip_createdir` which allows for some magic that the
  given directory name is created as an entry in the zip archive.

  If the given dir name argument is not within the basepath of
  the zip central directory then a real directory is created.
  Any EEXIST errors are not suppressed unlike with `zzip_createdir`

  Standard usage accepts a global/threaded/modular ZZIP_DIR pointer
  for all zip archive operations like in:

        ZZIP_DIR* zip = zzip_createdir (sysconfpath, 0755, zip);
         zzip_file_mkdir (zip, filepath[i], 0755);
         ZZIP_FILE* file = zzip_file_creat (zip, filename[i], 0644);
         zzip_write (file, buf, len);
         zzip_close (file); file = 0;
         zzip_closedir (zip); zip = 0;

  compare with `zzip_mkdir` inline macro which allows to
  collapse the examples script to

        #define zzip_savefile myproject_saveconfig
         #include <zzip/zzip.h>
         ZZIP_DIR* zzip_savefile = zzip_createdir (sysconfpath, 0755);
         zzip_mkdir (filepath[i], 0755);
         ZZIP_FILE* file = zzip_creat(filepath[i], 0644);
         zzip_write (file, buf, len);
         zzip_close (file); file = 0;
         zzip_closedir (zip_savefile);

  (../../zzip/write.c)

`ZZIP_FILE *`
`zzip_file_open` ``(ZZIP_DIR * dir, zzip_char_t* name, int o_mode)``
  <para> (zzip/file.c) </para>

  open an `ZZIP_FILE` from an already open `ZZIP_DIR` handle. Since
  we have a chance to reuse a cached `buf32k` and `ZZIP_FILE` memchunk
  this is the best choice to unpack multiple files.

  Note: the zlib supports 2..15 bit windowsize, hence we provide a 32k
  memchunk here... just to be safe.

  (../../zzip/file.c)

`zzip_ssize_t`
`zzip_file_read` ``(ZZIP_FILE * fp, char * buf, zzip_size_t len)``
  <para> (zzip/file.c) </para>

  <function>The zzip_file_read function</function>s read data from zip-contained file.

  It works like `read`(2) and will fill the given buffer with bytes from
  the opened file. It will return the number of bytes read, so if the `EOF`
  is encountered you will be prompted with the number of bytes actually read.

  This is the routines that needs the `buf32k` buffer, and it would have
  need for much more polishing but it does already work quite well.

  Note: the 32K buffer is rather big. The original inflate-algorithm
  required just that but the latest zlib would work just fine with
  a smaller buffer.

  (../../zzip/file.c)

`int`
`zzip_file_real` ``(ZZIP_FILE* fp)``
`int`
`zzip_dir_real` ``(ZZIP_DIR* dir)``
`void*`
`zzip_realdir` ``(ZZIP_DIR* dir)``
`int`
`zzip_realfd` ``(ZZIP_FILE* fp)``
  <para> (zzip/info.c) </para>

  <function>The zzip_file_real function</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.

  <function>The zzip_dir_real function</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.

  <function>The zzip_realdir function</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.

  <function>The zzip_realfd function</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.

  (../../zzip/info.c)

`ZZIP_FILE*`
`zzip_fopen` ``(zzip_char_t* filename, zzip_char_t* mode)``
`ZZIP_FILE*`
`zzip_freopen` ``(zzip_char_t* filename, zzip_char_t* mode, ZZIP_FILE* stream)``
  <para> (zzip/file.c) </para>

  <function>The zzip_fopen function</function> will `fopen`(3) a real/zipped file.

  It has some magic functionality builtin - it will first try to open
  the given filename as a normal file. If it does not
  exist, the given path to the filename (if any) is split into
  its directory-part and the file-part. A ".zip" extension is
  then added to the directory-part to create the name of a
  zip-archive. That zip-archive (if it exists) is being searched
  for the file-part, and if found a zzip-handle is returned.

  Note that if the file is found in the normal fs-directory the
  returned structure is mostly empty and the `zzip_read` call will
  use the libc `read` to obtain data. Otherwise a `zzip_file_open`
  is performed and any error mapped to `errno`(3).

  unlike the posix-wrapper `zzip_open` the mode-argument is
  a string which allows for more freedom to support the extra
  zzip modes called ZZIP_CASEINSENSITIVE and ZZIP_IGNOREPATH.
  Currently, this `zzip_fopen` call will convert the following
  characters in the mode-string into their corrsponding mode-bits:

  - `"r" : O_RDONLY :` read-only
  - `"b" : O_BINARY :` binary (win32 specific)
  - `"f" : O_NOCTTY :` no char device (unix)
  - `"i" : ZZIP_CASELESS :` inside zip file
  - `"*" : ZZIP_NOPATHS :` inside zip file only
  all other modes will be ignored for zip-contained entries
  but they are transferred for compatibility and portability,
  including these extra sugar bits:
  - `"x" : O_EXCL :` fail if file did exist
  - `"s" : O_SYNC :` synchronized access
  - `"n" : O_NONBLOCK :` nonblocking access
  - `"z#" : compression level :` for zlib
  - `"g#" : group access :` unix access bits
  - `"u#" : owner access :` unix access bits
  - `"o#" : world access :` unix access bits
  ... the access bits are in traditional unix bit format
  with 7 = read/write/execute, 6 = read/write, 4 = read-only.

  The default access mode is 0664, and the compression level
  is ignored since the lib can not yet write zip files, otherwise
  it would be the initialisation value for the zlib deflateInit
  where 0 = no-compression, 1 = best-speed, 9 = best-compression.

  <function>The zzip_freopen function</function> receives an additional argument pointing to
  a ZZIP_FILE* being already in use. If this extra argument is
  null then <function>the zzip_freopen function</function> is identical with calling `zzip_fopen`

  Per default, the old file stream is closed and only the internal
  structures associated with it are kept. These internal structures
  may be reused for the return value, and this is a lot quicker when
  the filename matches a zipped file that is incidently in the very
  same zip arch as the old filename wrapped in the stream struct.

  That's simply because the zip arch's central directory does not
  need to be read again. As an extension for <function>the zzip_freopen function</function>, if the
  mode-string contains a "q" then the old stream is not closed but
  left untouched, instead it is only given as a hint that a new
  file handle may share/copy the zip arch structures of the old file
  handle if that is possible, i.e when they are in the same zip arch.

  (../../zzip/file.c)

`static int`
`zzip_inflate_init` ``(ZZIP_FILE * fp, struct zzip_dir_hdr* hdr)``
  <para> (zzip/file.c) </para>

  call `inflateInit` and setup fp's iterator variables,
  used by lowlevel `_open` functions.

  (../../zzip/file.c)

`int`
`zzip_init_io` ``(zzip_plugin_io_handlers_t io, int flags)``
`zzip_plugin_io_t`
`zzip_get_default_io` ``()``
  <para> (zzip/plugin.c) </para>

  <function>The zzip_init_io function</function> initializes the users handler struct to default values
  being the posix io functions in default configured environments.

  <function>The zzip_get_default_io function</function> returns a zzip_plugin_io_t handle to static defaults
  wrapping the posix io file functions for actual file access.

  (../../zzip/plugin.c)

`zzip__new__ ZZIP_MEM_DISK*`
`zzip_mem_disk_fdopen` ``(int fd)``
  <para> create new diskdir handle. </para>

  wraps underlying zzip_disk_open.

  (../../zzip/memdisk.c)

`long`
`zzip_mem_disk_load` ``(ZZIP_MEM_DISK* dir, ZZIP_DISK* disk)``
  <para> parse central dir. </para>

  creates an internal copy of each entry converted to the local platform.
  returns: number of entries, or -1 on error (setting errno)

  (../../zzip/memdisk.c)

`zzip__new__ ZZIP_MEM_DISK*`
`zzip_mem_disk_open` ``(char* filename)``
  <para> create new diskdir handle. </para>

  wraps underlying zzip_disk_open.

  (../../zzip/memdisk.c)

`zzip__new__ ZZIP_MEM_ENTRY*`
`zzip_mem_entry_new` ``(ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry)``
  <para> convert a zip disk entry to internal format. </para>

  creates a new item parsing the information out of the various places
  in the zip archive. This is a good place to extend functionality if
  you have a project with extra requirements as you can push more bits
  right into the diskdir_entry for later usage in higher layers.
  returns: new item, or null on error (setting errno)

  (../../zzip/memdisk.c)

`int inline`
`zzip_mkdir` ``(zzip_char_t* name, int o_mode)``
`ZZIP_FILE* inline`
`zzip_creat` ``(zzip_char_t* name, int o_mode)``
  <para> create a zipped file/directory </para>

  <function>The zzip_mkdir function</function> creates a directory entry in the default zip-archive.
  If you did not specify a "#define zzip_savefile somevar"
  then the default zip-archive is null and all directories are
  created as real directories in the filesystem. <function>The zzip_mkdir function</function> is
  really a preprocessor macro or preferably an inline function
  around `zzip_file_mkdir`, there is no such symbol generated
  into the library. The prototype is modelled after the posix
  `mkdir`(2) call.

        #ifndef zzip_savefile
         #define zzip_savefile 0
         #endif
         #define zzip_mkdir(name,mode) \ -

  zzip_file_mkdir(zzip_savefile,name,mode)

  <function>The zzip_creat function</function> creates a file in the default zip-archive.
  If you did not specify a "#define zzip_savefile somevar"
  then the default zip-archive is null and all files are created
  as real files. <function>The zzip_creat function</function> is really a preprocessor macro
  or preferably an inline function around `zzip_file_creat`,
  there is no such symbol generated into the library. The prototype
  is modelled after the posix `creat`(2) call.

        #ifndef zzip_savefile
         #define zzip_savefile 0
         #endif
         #define zzip_creat(name,mode) \ -

  zzip_file_creat(zzip_savefile,name,mode)

  (../../zzip/write.c)

`void inline`
`zzip_mkfifo` ``(zzip_char_t* name, int o_mode)``
`void inline`
`zzip_sync` ``(void)``
  <para> start writing to the magic zzip_savefile </para>

  open a zip archive for writing via the magic zzip_savefile macro
  variable. The name and mode are given to `zzip_createdir` and
  the result is stored into `zzip_savefile` - if the `zzip_savefile`
  did already have a zzip_dir handle then it is automatically
  finalized with `zzip_sync` and the handle closed and the
  zzip_savefile variable reused for the new zip archive just started
  with this call. - <function>The zzip_mkfifo function</function> is really a preprocessor macro
  or preferably an inline function around `zzip_dir_create`, there
  is no such symbol generated into the library.

        #ifndef zzip_savefile
         #define zzip_savefile 0
         #endif
         #define zzip_start(name,mode,ext) \ -

  { if (zzip_savefile) zzip_closedir(zzip_savefile); \ - zzip_savefile = zzip_createdir(name,mode,ext); }
  <function>The zzip_mkfifo function</function> returns null on error or a zzip_dir handle on
  success. It is perfectly okay to continue with a null in the
  zzip_savefile variable since it makes subsequent calls to
  `zzip_creat` and `zzip_mkdir` to run as `creat`(2) / `mkdir`(2)
  on the real filesystem.

  finalize a zip archive thereby writing the central directory to
  the end of the file. If it was a real directory then we do just
  nothing - even that the prototype of the call itself is modelled
  to be similar to the posix `sync`(2) call. <function>The zzip_sync function</function> is
  really a preprocessor macro or preferably an inline function
  around `zzip_closedir`, there is no such symbol generated
  into the library.

        #ifndef zzip_savefile
         #define zzip_savefile 0
         #endif
         #define zzip_sync(name,mode) \ -

  { zzip_closedir(zzip_savefile); zzip_savefile = 0; }

  (../../zzip/write.c)

`ZZIP_FILE*`
`zzip_open` ``(zzip_char_t* filename, int o_flags)``
`ZZIP_FILE*`
`zzip_open_ext_io` ``(zzip_char_t* filename, int o_flags, int o_modes, zzip_strings_t* ext, zzip_plugin_io_t io)``
`ZZIP_FILE*`
`zzip_open_shared_io` ``(ZZIP_FILE* stream, zzip_char_t* filename, int o_flags, int o_modes, zzip_strings_t* ext, zzip_plugin_io_t io)``
  <para> (zzip/file.c) </para>

  <function>The zzip_open function</function> will `open`(2) a real/zipped file

  It has some magic functionality builtin - it will first try to open
  the given filename as a normal file. If it does not
  exist, the given path to the filename (if any) is split into
  its directory-part and the file-part. A ".zip" extension is
  then added to the directory-part to create the name of a
  zip-archive. That zip-archive (if it exists) is being searched
  for the file-part, and if found a zzip-handle is returned.

  Note that if the file is found in the normal fs-directory the
  returned structure is mostly empty and the `zzip_read` call will
  use the libc `read` to obtain data. Otherwise a `zzip_file_open`
  is performed and any error mapped to `errno`(3).

  There was a possibility to transfer zziplib-specific openmodes
  through o_flags but you should please not use them anymore and
  look into `zzip_open_ext_io` to submit them down. <function>The zzip_open function</function>
  is shallow in that it just extracts the zzipflags and calls

  - `
    zzip_open_ext_io(filename, o_flags, zzipflags|0664, 0, 0)`
  you must stop using this extra functionality (not well known
  anyway) since zzip_open might be later usable to open files
  for writing in which case the _EXTRAFLAGS will get in conflict.

  compare with `open`(2) and `zzip_fopen`

  <function>The zzip_open_ext_io function</function> uses explicit ext and io instead of the internal
  defaults, setting them to zero is equivalent to `zzip_open`

  note that the two flag types have been split into an o_flags
  (for fcntl-like openflags) and o_modes where the latter shall
  carry the zzip_flags and possibly accessmodes for unix filesystems.
  Since this version of zziplib can not write zipfiles, it is not
  yet used for anything else than zzip-specific modeflags.

  <function>The zzip_open_shared_io function</function> takes an extra stream argument - if a handle has been
  then ext/io can be left null and the new stream handle will pick up
  the ext/io. This should be used only in specific environment however
  since `zzip_file_real` does not store any ext-sequence.

  The benefit for <function>the zzip_open_shared_io function</function> comes in when the old file handle
  was openened from a file within a zip archive. When the new file
  is in the same zip archive then the internal zzip_dir structures
  will be shared. It is even quicker, as no check needs to be done
  anymore trying to guess the zip archive place in the filesystem,
  here we just check whether the zip archive's filepath is a prefix
  part of the filename to be opened.

  Note that <function>the zzip_open_shared_io function</function> is also used by `zzip_freopen` that
  will unshare the old handle, thereby possibly closing the handle.

  (../../zzip/file.c)

`ZZIP_DIR*`
`zzip_opendir` ``(zzip_char_t* filename)``
`ZZIP_DIR*`
`zzip_opendir_ext_io` ``(zzip_char_t* filename, int o_modes, zzip_strings_t* ext, zzip_plugin_io_t io)``
  <para> (zzip/dir.c) </para>

  <function>The zzip_opendir function</function> is the equivalent of `opendir`(3) for a realdir or zipfile.

  <function>The zzip_opendir function</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).

  <function>The zzip_opendir_ext_io function</function> uses explicit ext and io instead of the internal
  defaults, setting them to zero is equivalent to `zzip_opendir`

  (../../zzip/dir.c)

`zzip_ssize_t`
`zzip_read` ``(ZZIP_FILE * fp, char * buf, zzip_size_t len)``
`zzip_size_t`
`zzip_fread` ``(void *ptr, zzip_size_t size, zzip_size_t nmemb, ZZIP_FILE *file)``
  <para> (zzip/file.c) </para>

  <function>The zzip_read function</function> will read(2) data from a real/zipped file.

  the replacement for `read`(2) will fill the given buffer with bytes from
  the opened file. It will return the number of bytes read, so if the EOF
  is encountered you will be prompted with the number of bytes actually read.

  If the file-handle is wrapping a stat'able file then it will actually just
  perform a normal `read`(2)-call, otherwise `zzip_file_read` is called
  to decompress the data stream and any error is mapped to `errno`(3).

  `zzip_fread` -

  (../../zzip/file.c)

`ZZIP_DIRENT*`
`zzip_readdir` ``(ZZIP_DIR * dir)``
  <para> (zzip/dir.c) </para>

  <function>The zzip_readdir function</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/dir.c)

`int`
`zzip_rewind` ``(ZZIP_FILE *fp)``
  <para> (zzip/file.c) </para>

  <function>The zzip_rewind function</function> will rewind a real/zipped file.

  It seeks to the beginning of this file's data in the zip,
  or the beginning of the file for a stat'fd.

  (../../zzip/file.c)

`void`
`zzip_rewinddir` ``(ZZIP_DIR * dir)``
`zzip_off_t`
`zzip_telldir` ``(ZZIP_DIR* dir)``
`void`
`zzip_seekdir` ``(ZZIP_DIR* dir, zzip_off_t offset)``
  <para> (zzip/dir.c) </para>

  <function>The zzip_rewinddir function</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.

  <function>The zzip_telldir function</function> is the equivalent of `telldir`(2) for a realdir or zipfile.

  <function>The zzip_seekdir function</function> is the equivalent of `seekdir`(2) for a realdir or zipfile.

  (../../zzip/dir.c)

`zzip_off_t`
`zzip_seek` ``(ZZIP_FILE * fp, zzip_off_t offset, int whence)``
  <para> (zzip/file.c) </para>

  <function>The zzip_seek function</function> will perform a `lseek`(2) operation on a real/zipped file

  It will try to seek to the offset specified by offset, relative to whence,
  which is one of SEEK_SET, SEEK_CUR or SEEK_END.

  If the file-handle is wrapping a stat'able file then it will actually just
  perform a normal `lseek`(2)-call. Otherwise the relative offset
  is calculated, negative offsets are transformed into positive ones
  by rewinding the file, and then data is read until the offset is
  reached. This can make the function terribly slow, but this is
  how gzio implements it, so I'm not sure there is a better way
  without using the internals of the algorithm.

  (../../zzip/file.c)

`zzip_char_t*`
`zzip_strerror` ``(int errcode)``
`zzip_char_t*`
`zzip_strerror_of` ``(ZZIP_DIR* dir)``
  <para> (zzip/err.c) </para>

  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`

  <function>The zzip_strerror_of function</function> fetches the errorcode from the `DIR`-handle and
  runs it through `zzip_strerror` to obtain the static string
  describing the error.

  (../../zzip/err.c)

`zzip_off_t`
`zzip_tell` ``(ZZIP_FILE * fp)``
  <para> (zzip/file.c) </para>

  <function>The zzip_tell function</function> will `tell`(2) the current position in a real/zipped file

  It will return the current offset within the real/zipped file,
  measured in uncompressed bytes for the zipped-file case.

  If the file-handle is wrapping a stat'able file then it will actually just
  perform a normal `tell`(2)-call, otherwise the offset is
  calculated from the amount of data left and the total uncompressed
  size;

  (../../zzip/file.c)

`zzip_ssize_t`
`zzip_write` ``(ZZIP_FILE* file, const void* ptr, zzip_size_t len)``
`zzip_ssize_t`
`zzip_file_write` ``(ZZIP_FILE* file, const void* ptr, zzip_size_t len)``
`zzip_size_t`
`zzip_fwrite` ``(const void* ptr, zzip_size_t len, zzip_size_t multiply, ZZIP_FILE* file)``
  <para> write to zzip storage </para>

  <function>The zzip_write function</function> will write data to a file descriptor. If the file
  descriptor represents a real file then it will be forwarded to
  call posix `write`(2) directly. If it is a descriptor for a
  file within a zip directory then the data will be "deflated"
  using `zlib`(3) and appended to the zip archive file.

  <function>The zzip_file_write function</function> will write data to a file descriptor inside a zip
  archive. The data will be "deflated" using `zlib`(3) compression
  and appended to the end of the zip archive file. Only one file
  descriptor may be open per zzip_dir archive handle (fifo-like).

  <function>The zzip_file_write function</function> is not yet implemented, check for #def ZZIP_NO_CREAT
  It returns immediately -1 and sets errno=EROFS for indication.

  <function>The zzip_fwrite function</function> is the stdc variant for writing and the arguments
  are forwarded to `zzip_write` - the return value is floored to
  null as for STDC spec but there is no zzip_ferror call so far
  for the zziplib (later? is it actually needed?).

  <function>The zzip_fwrite function</function> is not yet implemented, check for #def ZZIP_NO_CREAT
  Write-support extends `zzip_close` with semantics to write out a
  file-trailer to the zip-archive leaving a name/offset marker in
  the (still-open) ZZIP_DIR handle.

  (../../zzip/write.c)