diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 30812ece..3e176460 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -180,7 +180,6 @@ add_executable(pihole-FTL $ $ $ - $ $ $ $ @@ -261,7 +260,6 @@ add_subdirectory(api) add_subdirectory(webserver) add_subdirectory(civetweb) add_subdirectory(cJSON) -add_subdirectory(microtar) add_subdirectory(miniz) add_subdirectory(ph7) add_subdirectory(database) diff --git a/src/microtar/CMakeLists.txt b/src/microtar/CMakeLists.txt deleted file mode 100644 index 597f3eeb..00000000 --- a/src/microtar/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -# Pi-hole: A black hole for Internet advertisements -# (c) 2023 Pi-hole, LLC (https://pi-hole.net) -# Network-wide ad blocking via your own hardware. -# -# FTL Engine -# /src/microtar/CMakeList.txt -# -# This file is copyright under the latest version of the EUPL. -# Please see LICENSE file for your rights under this license. - -set(sources - microtar-mmap.c - microtar-mmap.h - microtar.c - microtar.h - ) - -add_library(microtar OBJECT ${sources}) -target_compile_options(microtar PRIVATE) -target_include_directories(microtar PRIVATE ${PROJECT_SOURCE_DIR}/src) diff --git a/src/microtar/microtar-mmap.c b/src/microtar/microtar-mmap.c deleted file mode 100644 index bd0ae05c..00000000 --- a/src/microtar/microtar-mmap.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2017 rxi - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include - -#include -#include -#include -#include -#include - -#include "microtar.h" -#include "microtar-mmap.h" - -typedef struct { - char name[100]; - char mode[8]; - char owner[8]; - char group[8]; - char size[12]; - char mtime[12]; - char checksum[8]; - char type; - char linkname[100]; - char _padding[255]; -} mtar_raw_header_t; - -struct mmap_info { - int fd; - unsigned char *data; - size_t size; -}; - -static int file_write(mtar_t *tar, const void *data, size_t size) { - memcpy(((struct mmap_info*) tar->stream)->data + tar->pos, data, size); - return MTAR_ESUCCESS; -} - -static int file_read(mtar_t *tar, void *data, size_t size) { - memcpy(data, ((struct mmap_info*) tar->stream)->data + tar->pos, size); - return MTAR_ESUCCESS; -} - -static int file_seek(mtar_t *tar, size_t offset) { - tar->pos = offset; - if (tar->pos > ((struct mmap_info*) tar->stream)->size) { - return MTAR_ESEEKFAIL; - } - return MTAR_ESUCCESS; -} - -static int file_close(mtar_t *tar) { - munmap( - ((struct mmap_info*) tar->stream)->data, - ((struct mmap_info*) tar->stream)->size - ); - close(((struct mmap_info*) tar->stream)->fd); - return MTAR_ESUCCESS; -} - - -int mtar_open_mapped(mtar_t *tar, const char *filename) { - int err; - mtar_header_t h; - struct stat st; - struct mmap_info *info; - - /* Init tar struct and functions */ - memset(tar, 0, sizeof(*tar)); - tar->write = file_write; - tar->read = file_read; - tar->seek = file_seek; - tar->close = file_close; - - /* Open file */ - info = malloc(sizeof(struct mmap_info)); - - info->fd = open(filename, O_RDONLY); - if (info->fd == -1) { - mtar_close(tar); - return MTAR_EOPENFAIL; - } - /* Get file info */ - fstat(info->fd, &st); - /* Map file memory */ - info->data = mmap( - NULL, - st.st_size, - PROT_READ, - MAP_SHARED, - info->fd, - 0 - ); - info->size = st.st_size; - tar->stream = info; - /* Read first header to check it is valid if mode is `r` */ - err = mtar_read_header(tar, &h); - if (err != MTAR_ESUCCESS) { - mtar_close(tar); - return err; - } - mtar_rewind(tar); - - /* Return ok */ - return MTAR_ESUCCESS; -} - - -int mtar_get_mapped(mtar_t *tar, const char* filename, const void **ptr) { - int err; - mtar_header_t h; - - /* Rewind file */ - mtar_rewind(tar); - /* Find file point */ - while ( (err = mtar_read_header(tar, &h)) == MTAR_ESUCCESS ) { - if ( !strcmp(h.name, filename) ) { - tar->pos += sizeof(mtar_raw_header_t); - break; - } - mtar_next(tar); - } - /* Return mapped file pointer */ - *ptr = ((struct mmap_info*) tar->stream)->data + tar->pos; - return MTAR_ESUCCESS; -} - -int mtar_get_pointer(mtar_t *tar, const void **ptr) { - tar->pos += sizeof(mtar_raw_header_t); - /* Return pointer to data after header */ - *ptr = ((struct mmap_info*) tar->stream)->data + tar->pos; - return MTAR_ESUCCESS; -} diff --git a/src/microtar/microtar-mmap.h b/src/microtar/microtar-mmap.h deleted file mode 100644 index 054efbbd..00000000 --- a/src/microtar/microtar-mmap.h +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright (c) 2017 rxi - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MIT license. See `microtar.c` for details. - */ - -#ifndef MICROTAR_MMAP_H -#define MICROTAR_MMAP_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -int mtar_open_mapped(mtar_t *tar, const char *filename); -int mtar_get_mapped(mtar_t *tar, const char *filename, const void **data); -int mtar_get_pointer(mtar_t *tar, const void **ptr); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/microtar/microtar.c b/src/microtar/microtar.c deleted file mode 100644 index 2aaa9342..00000000 --- a/src/microtar/microtar.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * Copyright (c) 2017 rxi - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include -#include -#include - -#include "microtar.h" - -typedef struct { - char name[100]; - char mode[8]; - char owner[8]; - char group[8]; - char size[12]; - char mtime[12]; - char checksum[8]; - char type; - char linkname[100]; - char _padding[255]; -} mtar_raw_header_t; - - -static unsigned round_up(unsigned n, unsigned incr) { - return n + (incr - n % incr) % incr; -} - - -static unsigned checksum(const mtar_raw_header_t* rh) { - unsigned i; - unsigned char *p = (unsigned char*) rh; - unsigned res = 256; - for (i = 0; i < offsetof(mtar_raw_header_t, checksum); i++) { - res += p[i]; - } - for (i = offsetof(mtar_raw_header_t, type); i < sizeof(*rh); i++) { - res += p[i]; - } - return res; -} - - -static int tread(mtar_t *tar, void *data, size_t size) { - int err = tar->read(tar, data, size); - tar->pos += size; - return err; -} - - -static int twrite(mtar_t *tar, const void *data, size_t size) { - int err = tar->write(tar, data, size); - tar->pos += size; - return err; -} - - -static int write_null_bytes(mtar_t *tar, int n) { - int i, err; - char nul[MTAR_NULL_BLOCKSIZE]; - memset(nul, 0, sizeof(nul)); - while (n > 0) { - err = twrite(tar, &nul, n > MTAR_NULL_BLOCKSIZE ? MTAR_NULL_BLOCKSIZE : n); - if (err) { - return err; - } - n -= MTAR_NULL_BLOCKSIZE; - } - return MTAR_ESUCCESS; -} - - -static int raw_to_header(mtar_header_t *h, const mtar_raw_header_t *rh) { - unsigned chksum1, chksum2; - - /* If the checksum starts with a null byte we assume the record is NULL */ - if (*rh->checksum == '\0') { - return MTAR_ENULLRECORD; - } - - /* Build and compare checksum */ - chksum1 = checksum(rh); - sscanf(rh->checksum, "%o", &chksum2); - if (chksum1 != chksum2) { - return MTAR_EBADCHKSUM; - } - - /* Load raw header into header */ - sscanf(rh->mode, "%o", &h->mode); - sscanf(rh->owner, "%o", &h->owner); - sscanf(rh->size, "%o", &h->size); - sscanf(rh->mtime, "%o", &h->mtime); - h->type = rh->type; - strcpy(h->name, rh->name); - strcpy(h->linkname, rh->linkname); - - return MTAR_ESUCCESS; -} - - -static int header_to_raw(mtar_raw_header_t *rh, const mtar_header_t *h) { - unsigned chksum; - - /* Load header into raw header */ - memset(rh, 0, sizeof(*rh)); - sprintf(rh->mode, "%o", h->mode); - sprintf(rh->owner, "%o", h->owner); - sprintf(rh->size, "%o", h->size); - sprintf(rh->mtime, "%o", h->mtime); - rh->type = h->type ? h->type : MTAR_TREG; - strcpy(rh->name, h->name); - strcpy(rh->linkname, h->linkname); - - /* Calculate and write checksum */ - chksum = checksum(rh); - sprintf(rh->checksum, "%06o", chksum); - rh->checksum[7] = ' '; - - return MTAR_ESUCCESS; -} - - -const char* mtar_strerror(int err) { - switch (err) { - case MTAR_ESUCCESS : return "success"; - case MTAR_EFAILURE : return "failure"; - case MTAR_EOPENFAIL : return "could not open"; - case MTAR_EREADFAIL : return "could not read"; - case MTAR_EWRITEFAIL : return "could not write"; - case MTAR_ESEEKFAIL : return "could not seek"; - case MTAR_EBADCHKSUM : return "bad checksum"; - case MTAR_ENULLRECORD : return "null record"; - case MTAR_ENOTFOUND : return "file not found"; - } - return "unknown error"; -} - - -static int file_write(mtar_t *tar, const void *data, size_t size) { - size_t res = fwrite(data, 1, size, tar->stream); - return (res == size) ? MTAR_ESUCCESS : MTAR_EWRITEFAIL; -} - -static int file_read(mtar_t *tar, void *data, size_t size) { - size_t res = fread(data, 1, size, tar->stream); - return (res == size) ? MTAR_ESUCCESS : MTAR_EREADFAIL; -} - -static int file_seek(mtar_t *tar, size_t offset) { - size_t res = fseek(tar->stream, offset, SEEK_SET); - return (res == 0) ? MTAR_ESUCCESS : MTAR_ESEEKFAIL; -} - -static int file_close(mtar_t *tar) { - fclose(tar->stream); - return MTAR_ESUCCESS; -} - -static int mem_write(mtar_t *tar, const void *data, size_t size) { - mtar_mem_stream_t *mem = tar->stream; - - if(!mem || mem->pos + size >= mem->size) { - return MTAR_EWRITEFAIL; - } - - memcpy(mem->data + mem->pos, data, size); - mem->pos += size; - - return MTAR_ESUCCESS; -} - -static int mem_read(mtar_t *tar, void *data, size_t size) { - mtar_mem_stream_t *mem = tar->stream; - - if(!mem || mem->pos + size >= mem->size) { - return MTAR_EREADFAIL; - } - - memcpy(data, mem->data + mem->pos, size); - mem->pos += size; - - return MTAR_ESUCCESS; -} - -static int mem_seek(mtar_t *tar, size_t offset) { - mtar_mem_stream_t *mem = tar->stream; - - if(!mem || offset >= mem->size) - return MTAR_ESEEKFAIL; - - mem->pos = offset; - - return MTAR_ESUCCESS; -} - -static int mem_close(mtar_t *tar) { - tar->stream = NULL; - - return MTAR_ESUCCESS; -} - - -int mtar_init_mem_stream(mtar_mem_stream_t *mem, void *buff, size_t size) -{ - mem->data = buff; - mem->size = size; - mem->pos = 0; -} - - -int mtar_open_mem(mtar_t *tar, mtar_mem_stream_t *mem) { - int err; - mtar_header_t h; - - if ( !mem || !mem->data || !mem->size ) { - return MTAR_EOPENFAIL; - } - - memset(tar, 0, sizeof(*tar)); - tar->write = mem_write; - tar->read = mem_read; - tar->seek = mem_seek; - tar->close = mem_close; - - tar->stream = mem; - - return MTAR_ESUCCESS; -} - - -int mtar_open(mtar_t *tar, const char *filename, const char *mode) { - int err; - mtar_header_t h; - - /* Init tar struct and functions */ - memset(tar, 0, sizeof(*tar)); - tar->write = file_write; - tar->read = file_read; - tar->seek = file_seek; - tar->close = file_close; - - /* Assure mode is always binary */ - if ( strchr(mode, 'r') ) mode = "rb"; - if ( strchr(mode, 'w') ) mode = "wb"; - if ( strchr(mode, 'a') ) mode = "ab"; - /* Open file */ - tar->stream = fopen(filename, mode); - if (!tar->stream) { - return MTAR_EOPENFAIL; - } - /* Read first header to check it is valid if mode is `r` */ - if (*mode == 'r') { - err = mtar_read_header(tar, &h); - if (err != MTAR_ESUCCESS) { - mtar_close(tar); - return err; - } - } - - /* Return ok */ - return MTAR_ESUCCESS; -} - - -int mtar_close(mtar_t *tar) { - return tar->close(tar); -} - - -int mtar_seek(mtar_t *tar, size_t pos) { - int err = tar->seek(tar, pos); - tar->pos = pos; - return err; -} - - -int mtar_rewind(mtar_t *tar) { - tar->remaining_data = 0; - tar->last_header = 0; - return mtar_seek(tar, 0); -} - - -int mtar_next(mtar_t *tar) { - int err, n; - mtar_header_t h; - /* Load header */ - err = mtar_read_header(tar, &h); - if (err) { - return err; - } - /* Seek to next record */ - n = round_up(h.size, 512) + sizeof(mtar_raw_header_t); - return mtar_seek(tar, tar->pos + n); -} - - -int mtar_find(mtar_t *tar, const char *name, mtar_header_t *h) { - int err; - mtar_header_t header; - /* Start at beginning */ - err = mtar_rewind(tar); - if (err) { - return err; - } - /* Iterate all files until we hit an error or find the file */ - while ( (err = mtar_read_header(tar, &header)) == MTAR_ESUCCESS ) { - if ( !strcmp(header.name, name) ) { - if (h) { - *h = header; - } - return MTAR_ESUCCESS; - } - mtar_next(tar); - } - /* Return error */ - if (err == MTAR_ENULLRECORD) { - err = MTAR_ENOTFOUND; - } - return err; -} - - -int mtar_read_header(mtar_t *tar, mtar_header_t *h) { - int err; - mtar_raw_header_t rh; - /* Save header position */ - tar->last_header = tar->pos; - /* Read raw header */ - err = tread(tar, &rh, sizeof(rh)); - if (err) { - return err; - } - /* Seek back to start of header */ - err = mtar_seek(tar, tar->last_header); - if (err) { - return err; - } - /* Load raw header into header struct and return */ - return raw_to_header(h, &rh); -} - - -int mtar_read_data(mtar_t *tar, void *ptr, size_t size) { - int err; - /* If we have no remaining data then this is the first read, we get the size, - * set the remaining data and seek to the beginning of the data */ - if (tar->remaining_data == 0) { - mtar_header_t h; - /* Read header */ - err = mtar_read_header(tar, &h); - if (err) { - return err; - } - /* Seek past header and init remaining data */ - err = mtar_seek(tar, tar->pos + sizeof(mtar_raw_header_t)); - if (err) { - return err; - } - tar->remaining_data = h.size; - } - /* Read data */ - err = tread(tar, ptr, size); - if (err) { - return err; - } - tar->remaining_data -= size; - /* If there is no remaining data we've finished reading and seek back to the - * header */ - if (tar->remaining_data == 0) { - return mtar_seek(tar, tar->last_header); - } - return MTAR_ESUCCESS; -} - - -int mtar_write_header(mtar_t *tar, const mtar_header_t *h) { - mtar_raw_header_t rh; - /* Build raw header and write */ - header_to_raw(&rh, h); - tar->remaining_data = h->size; - return twrite(tar, &rh, sizeof(rh)); -} - - -int mtar_write_file_header(mtar_t *tar, const char *name, size_t size) { - mtar_header_t h; - /* Build header */ - memset(&h, 0, sizeof(h)); - strcpy(h.name, name); - h.size = size; - h.type = MTAR_TREG; - h.mode = 0664; - /* Write header */ - return mtar_write_header(tar, &h); -} - - -int mtar_write_dir_header(mtar_t *tar, const char *name) { - mtar_header_t h; - /* Build header */ - memset(&h, 0, sizeof(h)); - strcpy(h.name, name); - h.type = MTAR_TDIR; - h.mode = 0775; - /* Write header */ - return mtar_write_header(tar, &h); -} - - -int mtar_write_data(mtar_t *tar, const void *data, size_t size) { - int err; - /* Write data */ - err = twrite(tar, data, size); - if (err) { - return err; - } - tar->remaining_data -= size; - /* Write padding if we've written all the data for this file */ - if (tar->remaining_data == 0) { - return write_null_bytes(tar, round_up(tar->pos, 512) - tar->pos); - } - return MTAR_ESUCCESS; -} - - -int mtar_finalize(mtar_t *tar) { - /* Write two NULL records */ - return write_null_bytes(tar, sizeof(mtar_raw_header_t) * 2); -} diff --git a/src/microtar/microtar.h b/src/microtar/microtar.h deleted file mode 100644 index 4891db1a..00000000 --- a/src/microtar/microtar.h +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Copyright (c) 2017 rxi - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MIT license. See `microtar.c` for details. - */ - -#ifndef MICROTAR_H -#define MICROTAR_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include -#include - -#define MTAR_VERSION "0.2.0" -#define MTAR_NULL_BLOCKSIZE 16 - -enum { - MTAR_ESUCCESS = 0, - MTAR_EFAILURE = -1, - MTAR_EOPENFAIL = -2, - MTAR_EREADFAIL = -3, - MTAR_EWRITEFAIL = -4, - MTAR_ESEEKFAIL = -5, - MTAR_EBADCHKSUM = -6, - MTAR_ENULLRECORD = -7, - MTAR_ENOTFOUND = -8 -}; - -enum { - MTAR_TREG = '0', - MTAR_TLNK = '1', - MTAR_TSYM = '2', - MTAR_TCHR = '3', - MTAR_TBLK = '4', - MTAR_TDIR = '5', - MTAR_TFIFO = '6' -}; - -typedef struct { - unsigned mode; - unsigned owner; - unsigned size; - unsigned mtime; - unsigned type; - char name[100]; - char linkname[100]; -} mtar_header_t; - - -typedef struct mtar_t mtar_t; - -struct mtar_t { - int (*read)(mtar_t *tar, void *data, size_t size); - int (*write)(mtar_t *tar, const void *data, size_t size); - int (*seek)(mtar_t *tar, size_t pos); - int (*close)(mtar_t *tar); - void *stream; - size_t pos; - size_t remaining_data; - size_t last_header; -}; - -struct mtar_mem_stream_t { - char *data; - size_t size; - size_t pos; -}; - -typedef struct mtar_mem_stream_t mtar_mem_stream_t; - - -const char* mtar_strerror(int err); - -int mtar_init_mem_stream(mtar_mem_stream_t *mem, void *buff, size_t size); - -int mtar_open_mem(mtar_t *tar, mtar_mem_stream_t *mem); -int mtar_open(mtar_t *tar, const char *filename, const char *mode); -int mtar_close(mtar_t *tar); - -int mtar_seek(mtar_t *tar, size_t pos); -int mtar_rewind(mtar_t *tar); -int mtar_next(mtar_t *tar); -int mtar_find(mtar_t *tar, const char *name, mtar_header_t *h); -int mtar_read_header(mtar_t *tar, mtar_header_t *h); -int mtar_read_data(mtar_t *tar, void *ptr, size_t size); - -int mtar_write_header(mtar_t *tar, const mtar_header_t *h); -int mtar_write_file_header(mtar_t *tar, const char *name, size_t size); -int mtar_write_dir_header(mtar_t *tar, const char *name); -int mtar_write_data(mtar_t *tar, const void *data, size_t size); -int mtar_finalize(mtar_t *tar); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/miniz/compression.c b/src/miniz/compression.c index d4246de8..40aca896 100644 --- a/src/miniz/compression.c +++ b/src/miniz/compression.c @@ -37,7 +37,7 @@ static bool deflate_buffer(const unsigned char *buffer_uncompressed, const mz_ul int ret = compress2(*buffer_compressed, size_compressed, buffer_uncompressed, size_uncompressed, Z_BEST_COMPRESSION); if(ret != Z_OK) { - log_warn("Failed to compress: %s (%d)", zError(ret), ret); + log_warn("Failed to compress: %s", zError(ret)); return false; } @@ -101,97 +101,6 @@ static bool deflate_buffer(const unsigned char *buffer_uncompressed, const mz_ul return true; } -bool deflate_file(const char *infile, const char *outfile, bool verbose) -{ - // Read entire file into memory - FILE *fp = fopen(infile, "rb"); - if(fp == NULL) - { - log_warn("Failed to open %s: %s (%d)", infile, strerror(errno), errno); - return false; - } - - // Get file size - fseek(fp, 0, SEEK_END); - const mz_ulong size_uncompressed = ftell(fp); - fseek(fp, 0, SEEK_SET); - - // Read file into memory - unsigned char *buffer_uncompressed = malloc(size_uncompressed); - if(buffer_uncompressed == NULL) - { - log_warn("Failed to allocate %lu bytes of memory", (unsigned long)size_uncompressed); - fclose(fp); - return false; - } - if(fread(buffer_uncompressed, 1, size_uncompressed, fp) != size_uncompressed) - { - log_warn("Failed to read %lu bytes from %s", (unsigned long)size_uncompressed, infile); - fclose(fp); - free(buffer_uncompressed); - return false; - } - fclose(fp); - - unsigned char *buffer_compressed = NULL; - mz_ulong size_compressed = 0; - bool success = deflate_buffer(buffer_uncompressed, size_uncompressed, - &buffer_compressed, &size_compressed); - - // Free memory - free(buffer_uncompressed); - - // Check if compression was successful - if(!success) - { - log_warn("Failed to compress %s", infile); - free(buffer_uncompressed); - if(buffer_compressed) - free(buffer_compressed); - fclose(fp); - return false; - } - - // Create compressed file - fp = fopen(outfile, "wb"); - if(fp == NULL) - { - log_warn("Failed to open %s: %s (%d)", outfile, strerror(errno), errno); - free(buffer_uncompressed); - free(buffer_compressed); - return false; - } - if(fwrite(buffer_compressed, sizeof(char), size_compressed, fp) != size_compressed) - { - log_warn("Failed to write %lu bytes to %s", (unsigned long)size_compressed, outfile); - fclose(fp); - free(buffer_uncompressed); - free(buffer_compressed); - return false; - } - fclose(fp); - - free(buffer_compressed); - - if(verbose) - { - // Print compression ratio - // Compressed size = size of compressed data - // + 10 bytes for GZIP header - // + 8 bytes for GZIP footer - const size_t csize = size_compressed - (2 + 4) + 10 + 8; - double raw_size, comp_size; - char raw_prefix[2], comp_prefix[2]; - format_memory_size(raw_prefix, size_uncompressed, &raw_size); - format_memory_size(comp_prefix, csize, &comp_size); - log_info("Compressed %s (%.1f%sB) to %s (%.1f%sB), %.1f%% size reduction", - infile, raw_size, raw_prefix, outfile, comp_size, comp_prefix, - 100.0 - 100.0*csize / size_uncompressed); - } - - return true; -} - static bool inflate_buffer(unsigned char *buffer_compressed, mz_ulong size_compressed, unsigned char **buffer_uncompressed, mz_ulong *size_uncompressed) { @@ -356,7 +265,7 @@ static bool inflate_buffer(unsigned char *buffer_compressed, mz_ulong size_compr int ret = mz_uncompress2_raw(*buffer_uncompressed, size_uncompressed, buffer_compressed, &size_compressed); if(ret != Z_OK) { - log_warn("Failed to uncompress: %s (%d)", zError(ret), ret); + log_warn("Failed to uncompress: %s", zError(ret)); return false; } @@ -376,7 +285,7 @@ bool inflate_file(const char *infile, const char *outfile, bool verbose) FILE *fp = fopen(infile, "rb"); if(fp == NULL) { - log_warn("Failed to open %s: %s (%d)", infile, strerror(errno), errno); + log_warn("Failed to open %s: %s", infile, strerror(errno)); return false; } @@ -421,7 +330,7 @@ bool inflate_file(const char *infile, const char *outfile, bool verbose) fp = fopen(outfile, "wb"); if(fp == NULL) { - log_warn("Failed to open %s: %s (%d)", outfile, strerror(errno), errno); + log_warn("Failed to open %s: %s", outfile, strerror(errno)); return false; } if(fwrite(buffer_uncompressed, sizeof(char), size_uncompressed, fp) != size_uncompressed) @@ -449,6 +358,97 @@ bool inflate_file(const char *infile, const char *outfile, bool verbose) return true; } +bool deflate_file(const char *infile, const char *outfile, bool verbose) +{ + // Read entire file into memory + FILE *fp = fopen(infile, "rb"); + if(fp == NULL) + { + log_warn("Failed to open %s: %s", infile, strerror(errno)); + return false; + } + + // Get file size + fseek(fp, 0, SEEK_END); + const mz_ulong size_uncompressed = ftell(fp); + fseek(fp, 0, SEEK_SET); + + // Read file into memory + unsigned char *buffer_uncompressed = malloc(size_uncompressed); + if(buffer_uncompressed == NULL) + { + log_warn("Failed to allocate %lu bytes of memory", (unsigned long)size_uncompressed); + fclose(fp); + return false; + } + if(fread(buffer_uncompressed, 1, size_uncompressed, fp) != size_uncompressed) + { + log_warn("Failed to read %lu bytes from %s", (unsigned long)size_uncompressed, infile); + fclose(fp); + free(buffer_uncompressed); + return false; + } + fclose(fp); + + unsigned char *buffer_compressed = NULL; + mz_ulong size_compressed = 0; + bool success = deflate_buffer(buffer_uncompressed, size_uncompressed, + &buffer_compressed, &size_compressed); + + // Free memory + free(buffer_uncompressed); + + // Check if compression was successful + if(!success) + { + log_warn("Failed to compress %s", infile); + free(buffer_uncompressed); + if(buffer_compressed) + free(buffer_compressed); + fclose(fp); + return false; + } + + // Create compressed file + fp = fopen(outfile, "wb"); + if(fp == NULL) + { + log_warn("Failed to open %s: %s", outfile, strerror(errno)); + free(buffer_uncompressed); + free(buffer_compressed); + return false; + } + if(fwrite(buffer_compressed, sizeof(char), size_compressed, fp) != size_compressed) + { + log_warn("Failed to write %lu bytes to %s", (unsigned long)size_compressed, outfile); + fclose(fp); + free(buffer_uncompressed); + free(buffer_compressed); + return false; + } + fclose(fp); + + free(buffer_compressed); + + if(verbose) + { + // Print compression ratio + // Compressed size = size of compressed data + // + 10 bytes for GZIP header + // + 8 bytes for GZIP footer + const size_t csize = size_compressed - (2 + 4) + 10 + 8; + double raw_size, comp_size; + char raw_prefix[2], comp_prefix[2]; + format_memory_size(raw_prefix, size_uncompressed, &raw_size); + format_memory_size(comp_prefix, csize, &comp_size); + log_info("Compressed %s (%.1f%sB) to %s (%.1f%sB), %.1f%% size reduction", + infile, raw_size, raw_prefix, outfile, comp_size, comp_prefix, + 100.0 - 100.0*csize / size_uncompressed); + } + + return true; +} + // mz_uncompress2_raw() is a copy of mz_uncompress2() from miniz.c with the // exception of not checking the ZLIB header (first 2 bytes) and the ZLIB // trailer (last 4 bytes). While we could reconstruct the ZLIB header from the