diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/zziplib/zzip/mmapped.c')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/zziplib/zzip/mmapped.c | 566 |
1 files changed, 0 insertions, 566 deletions
diff --git a/Build/source/texk/web2c/luatexdir/zziplib/zzip/mmapped.c b/Build/source/texk/web2c/luatexdir/zziplib/zzip/mmapped.c deleted file mode 100644 index 645c4de6d45..00000000000 --- a/Build/source/texk/web2c/luatexdir/zziplib/zzip/mmapped.c +++ /dev/null @@ -1,566 +0,0 @@ -/* - * NOTE: this is part of libzzipmmapped (i.e. it is not libzzip). - * - * These routines are fully independent from the traditional zzip - * implementation. They assume a readonly mmapped sharedmem block - * representing a complete zip file. The functions show how to - * parse the structure, find files and return a decoded bytestream. - * - * These routines are a bit simple and really here for documenting - * the way to access a zip file. The complexity of zip access comes - * from staggered reading of bytes and reposition of a filepointer in - * a big archive with lots of files and long compressed datastreams. - * Plus varaints of drop-in stdio replacements, obfuscation routines, - * auto fileextensions, drop-in dirent replacements, and so on... - * - * Author: - * Guido Draheim <guidod@gmx.de> - * - * Copyright (c) 2003,2004 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 - */ - -#ifdef __linux__ -#define _GNU_SOURCE _glibc_developers_are_idiots_to_call_this_gnu_specific_ -#endif - -#define _ZZIP_DISK_FILE_STRUCT 1 - -#include <zzip/types.h> - -#include <stdlib.h> -#include <sys/stat.h> - -#if defined ZZIP_HAVE_UNISTD_H -#include <unistd.h> -#elif defined ZZIP_HAVE_IO_H -#include <io.h> -#endif - -#if defined ZZIP_HAVE_STRING_H -#include <string.h> -#endif -#if defined ZZIP_HAVE_STRINGS_H -#include <strings.h> -#endif - -#include <zlib.h> -#include <zzip/mmapped.h> -#include <zzip/format.h> -#include <zzip/fetch.h> -#include <zzip/__mmap.h> -#include <zzip/__fnmatch.h> - -#if __STDC_VERSION__+0 > 199900L -#define ___ -#define ____ -#else -#define ___ { -#define ____ } -#endif - -/** => zzip_disk_mmap - * This function does primary initialization of a disk-buffer struct. - */ -int -zzip_disk_init(ZZIP_DISK* disk, void* buffer, zzip_size_t buflen) -{ - disk->buffer = (zzip_byte_t*) buffer; - disk->endbuf = (zzip_byte_t*) buffer + buflen; - disk->reserved = 0; - disk->flags = 0; - disk->mapped = 0; - /* do not touch disk->user */ - /* do not touch disk->code */ - return 0; -} - -/** => zzip_disk_mmap - * This function allocates a new disk-buffer with => malloc(3) - */ -zzip__new__ ZZIP_DISK* -zzip_disk_new(void) -{ - ZZIP_DISK* disk = malloc(sizeof(disk)); - if (! disk) return disk; - zzip_disk_init (disk, 0, 0); - return disk; -} - -/** turn a filehandle into a mmapped zip disk archive handle - * - * This 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. - */ -zzip__new__ ZZIP_DISK* -zzip_disk_mmap(int fd) -{ - struct stat st; - if (fstat (fd, &st) || !st.st_size) return 0; - ___ ZZIP_DISK* disk = zzip_disk_new (); if (! disk) return 0; - disk->buffer = _zzip_mmap (& zzip->mapped, fd, 0, st.st_size); - if (disk->buffer == MAP_FAILED) { free (disk); return 0; } - disk->endbuf = disk->buffer + st.st_size; - return disk; ____; -} - -/** => zzip_disk_mmap - * This 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. - */ -int -zzip_disk_munmap(ZZIP_DISK* disk) -{ - if (! disk) return 0; - _zzip_munmap (disk->mapped, disk->buffer, disk->endbuf-disk->buffer); - free (disk); - return 0; -} - -/** => zzip_disk_mmap - * - * This 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. - */ -ZZIP_DISK* zzip__new__ -zzip_disk_open(char* filename) -{ -# ifndef O_BINARY -# define O_BINARY 0 -# endif - struct stat st; - if (stat (filename, &st) || !st.st_size) return 0; - ___ int fd = open (filename, O_RDONLY|O_BINARY); - if (fd <= 0) return 0; - ___ ZZIP_DISK* disk = zzip_disk_mmap (fd); - if (disk) return disk; - ___ zzip_byte_t* buffer = malloc (st.st_size); - if (! buffer) return 0; - if ((st.st_size == read (fd, buffer, st.st_size)) && - (disk = zzip_disk_new ())) - { - disk->buffer = buffer; - disk->endbuf = buffer+st.st_size; - disk->mapped = -1; - }else free (buffer); - return disk; ____;____;____; -} - -/** => zzip_disk_mmap - * - * This 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. - */ -int -zzip_disk_close(ZZIP_DISK* disk) -{ - if (! disk) return 0; - if (disk->mapped != -1) return zzip_disk_munmap (disk); - free (disk->buffer); - free (disk); - return 0; -} - -/* ====================================================================== */ -/* helper functions */ - -#ifdef ZZIP_HAVE_STRNDUP -#define _zzip_strndup strndup -#else -/* if your system does not have strndup: */ -zzip__new__ static char* _zzip_strndup(char* p, int maxlen) -{ - if (! p) return 0; - ___ zzip_byte_t* r = malloc (maxlen+1); - if (! r) return r; - strncpy (r, p, maxlen); - r[maxlen] = '\0'; - return r; ____; -} -#endif - -#if defined ZZIP_HAVE_STRCASECMP || defined strcasecmp -#define _zzip_strcasecmp strcasecmp -#else -/* if your system does not have strcasecmp: */ -static int _zzip_strcasecmp(char* __zzip_restrict a, char* _zzip_restrict b) -{ - if (! a) return (b) ? 1 : 0; - if (! b) return -1; - while (1) - { - int v = tolower(*a) - tolower(*b); - if (v) return v; - if (! *a) return 1; - if (! *b) return -1; - a++; b++; - } -} -#endif - -/** helper functions for (mmapped) zip access api - * - * This 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. - */ -zzip_byte_t* -zzip_disk_entry_to_data(ZZIP_DISK* disk, struct zzip_disk_entry* entry) -{ - struct zzip_file_header* file = - zzip_disk_entry_to_file_header(disk, entry); - if (file) return zzip_file_header_to_data (file); - return 0; -} - -/** => zzip_disk_entry_to_data - * This 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 - */ -struct zzip_file_header* -zzip_disk_entry_to_file_header(ZZIP_DISK* disk, struct zzip_disk_entry* entry) -{ - zzip_byte_t* file_header = /* (struct zzip_file_header*) */ - (disk->buffer + zzip_disk_entry_fileoffset (entry)); - if (disk->buffer > file_header || file_header >= disk->endbuf) - return 0; - return (struct zzip_file_header*) file_header; -} - -/** => zzip_disk_entry_to_data - * This 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__new__ char* -zzip_disk_entry_strdup_name(ZZIP_DISK* disk, struct zzip_disk_entry* entry) -{ - if (! disk || ! entry) return 0; - - ___ char* name; zzip_size_t len; - struct zzip_file_header* file; - if ((len = zzip_disk_entry_namlen (entry))) - name = zzip_disk_entry_to_filename (entry); - else if ((file = zzip_disk_entry_to_file_header (disk, entry)) && - (len = zzip_file_header_namlen (file))) - name = zzip_file_header_to_filename (file); - else - return 0; - - if ((zzip_byte_t*) name < disk->buffer || - (zzip_byte_t*) name+len > disk->endbuf) - return 0; - - return _zzip_strndup (name, len); ____; -} - -/** => zzip_disk_entry_to_data - * This function is similar creating a reference to a zero terminated - * string but it can only exist in the zip central directory entry. - */ -zzip__new__ char* -zzip_disk_entry_strdup_comment(ZZIP_DISK* disk, struct zzip_disk_entry* entry) -{ - if (! disk || ! entry) return 0; - - ___ char* text; zzip_size_t len; - if ((len = zzip_disk_entry_comment (entry))) - text = zzip_disk_entry_to_comment (entry); - else - return 0; - - if ((zzip_byte_t*) text < disk->buffer || - (zzip_byte_t*) text+len > disk->endbuf) - return 0; - - return _zzip_strndup (text, len); ____; -} - -/* ====================================================================== */ - -/** => zzip_disk_findfile - * - * This 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. - */ -struct zzip_disk_entry* -zzip_disk_findfirst(ZZIP_DISK* disk) -{ - if (disk->buffer > disk->endbuf-sizeof(struct zzip_disk_trailer)) - return 0; - ___ zzip_byte_t* p = disk->endbuf-sizeof(struct zzip_disk_trailer); - for (; p >= disk->buffer ; p--) - { - zzip_byte_t* root; /* (struct zzip_disk_entry*) */ - if (zzip_disk_trailer_check_magic(p)) { - root = disk->buffer + zzip_disk_trailer_get_rootseek ( - (struct zzip_disk_trailer*)p); - if (root > p) - { /* the first disk_entry is after the disk_trailer? can't be! */ - zzip_size_t rootsize = zzip_disk_trailer_get_rootsize ( - (struct zzip_disk_trailer*)p); - if (disk->buffer+rootsize > p) continue; - /* a common brokeness that can be fixed: we just assume the - * central directory was written directly before the trailer:*/ - root = p - rootsize; - } - } else if (zzip_disk64_trailer_check_magic(p)) { - if (sizeof(void*) < 8) return 0; /* EOVERFLOW */ - root = disk->buffer + zzip_disk64_trailer_get_rootseek ( - (struct zzip_disk64_trailer*)p); - if (root > p) continue; - } else continue; - - if (root < disk->buffer) continue; - if (zzip_disk_entry_check_magic(root)) - return (struct zzip_disk_entry*) root; - }____; - return 0; -} - -/** => zzip_disk_findfile - * - * This 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. - */ -struct zzip_disk_entry* -zzip_disk_findnext(ZZIP_DISK* disk, struct zzip_disk_entry* entry) -{ - if ((zzip_byte_t*)entry < disk->buffer || - (zzip_byte_t*)entry > disk->endbuf-sizeof(entry) || - ! zzip_disk_entry_check_magic (entry) || - zzip_disk_entry_sizeto_end (entry) > 64*1024) - return 0; - entry = zzip_disk_entry_to_next_entry (entry); - if ((zzip_byte_t*)entry > disk->endbuf-sizeof(entry) || - ! zzip_disk_entry_check_magic (entry) || - zzip_disk_entry_sizeto_end (entry) > 64*1024 || - zzip_disk_entry_skipto_end (entry) + sizeof(entry) > disk->endbuf) - return 0; - else - return entry; -} - -/** search for files in the (mmapped) zip central directory - * - * This 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). - */ -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* entry = (! after ? zzip_disk_findfirst (disk) - : zzip_disk_findnext (disk, after)); - if (! compare) - compare = (zzip_strcmp_fn_t)( (disk->flags&1) ? - (_zzip_strcasecmp) : (strcmp)); - for (; entry ; entry = zzip_disk_findnext (disk, entry)) - { - /* filenames within zip files are often not null-terminated! */ - char* realname = zzip_disk_entry_strdup_name (disk, entry); - if (realname && ! compare(filename, realname)) - { - free (realname); - return entry; - } - free (realname); - } - return 0; -} - -/** => zzip_disk_findfile - * - * This 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. - */ -struct zzip_disk_entry* -zzip_disk_findmatch(ZZIP_DISK* disk, char* filespec, - struct zzip_disk_entry* after, - zzip_fnmatch_fn_t compare, int flags) -{ - struct zzip_disk_entry* entry = (! after ? zzip_disk_findfirst (disk) - : zzip_disk_findnext (disk, after)); - if (! compare) { - compare = (zzip_fnmatch_fn_t) _zzip_fnmatch; - if (disk->flags&1) disk->flags |= _zzip_fnmatch_CASEFOLD; - } - for (; entry ; entry = zzip_disk_findnext (disk, entry)) - { - /* filenames within zip files are often not null-terminated! */ - char* realname = zzip_disk_entry_strdup_name(disk, entry); - if (realname && ! compare(filespec, realname, flags)) - { - free (realname); - return entry; - } - free (realname); - } - return 0; -} - -/* ====================================================================== */ - -/** => zzip_disk_fopen - * - * the ZZIP_DISK_FILE* is rather simple in just encapsulating the - * arguments given to this 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. - */ -zzip__new__ ZZIP_DISK_FILE* -zzip_disk_entry_fopen (ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry) -{ - /* keep this in sync with zzip_mem_entry_fopen */ - struct zzip_file_header* header = - zzip_disk_entry_to_file_header (disk, entry); - if (! header) return 0; - ___ ZZIP_DISK_FILE* file = malloc(sizeof(ZZIP_DISK_FILE)); - if (! file) return file; - file->buffer = disk->buffer; - file->endbuf = disk->endbuf; - file->avail = zzip_file_header_usize (header); - - if (! file->avail || zzip_file_header_data_stored (header)) - { file->stored = zzip_file_header_to_data (header); return file; } - - file->stored = 0; - file->zlib.opaque = 0; - file->zlib.zalloc = Z_NULL; - file->zlib.zfree = Z_NULL; - file->zlib.avail_in = zzip_file_header_csize (header); - file->zlib.next_in = zzip_file_header_to_data (header); - - if (! zzip_file_header_data_deflated (header) || - inflateInit2 (& file->zlib, -MAX_WBITS) != Z_OK) - { free (file); return 0; } - - return file; ____; -} - -/** openening a file part wrapped within a (mmapped) zip archive - * - * This 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 - */ -zzip__new__ ZZIP_DISK_FILE* -zzip_disk_fopen (ZZIP_DISK* disk, char* filename) -{ - ZZIP_DISK_ENTRY* entry = zzip_disk_findfile (disk, filename, 0, 0); - if (! entry) return 0; else return zzip_disk_entry_fopen (disk, entry); -} - - -/** => zzip_disk_fopen - * - * This 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. - */ -zzip_size_t -zzip_disk_fread (void* ptr, zzip_size_t sized, zzip_size_t nmemb, - ZZIP_DISK_FILE* file) -{ - zzip_size_t size = sized*nmemb; - if (size > file->avail) size = file->avail; - if (file->stored) - { - memcpy (ptr, file->stored, size); - file->stored += size; - file->avail -= size; - return size; - } - - file->zlib.avail_out = sized*nmemb; - file->zlib.next_out = ptr; - ___ zzip_size_t total_old = file->zlib.total_out; - ___ int err = inflate (& file->zlib, Z_NO_FLUSH); - if (err == Z_STREAM_END) - file->avail = 0; - else if (err == Z_OK) - file->avail -= file->zlib.total_out - total_old; - else - return 0; - return file->zlib.total_out - total_old; - ____;____; -} - -/** => zzip_disk_fopen - * This function releases any zlib decoder info needed for decompression - * and dumps the ZZIP_DISK_FILE* then. - */ -int -zzip_disk_fclose (ZZIP_DISK_FILE* file) -{ - if (! file->stored) - inflateEnd (& file->zlib); - free (file); - return 0; -} - -/** => zzip_disk_fopen - * - * This 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. - */ -int -zzip_disk_feof (ZZIP_DISK_FILE* file) -{ - return ! file || ! file->avail; -} |