diff options
Diffstat (limited to 'src/gzip.c')
-rw-r--r-- | src/gzip.c | 263 |
1 files changed, 0 insertions, 263 deletions
diff --git a/src/gzip.c b/src/gzip.c deleted file mode 100644 index 819a4e9..0000000 --- a/src/gzip.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (C) 2023 Patrick McDermott - * - * This file is part of opkg-opk. - * - * opkg-opk is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * opkg-opk is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with opkg-opk. If not, see <https://www.gnu.org/licenses/>. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <zlib.h> -#include "defs.h" -#include "gzip.h" -#include "ustar.h" - -#define OPKG_OPK_GZIP_WINDOW_BITS_ (15 + 16) - -enum _opkg_opk_gzip_dir { - _OPKG_OPK_GZIP_DIR_READ, - _OPKG_OPK_GZIP_DIR_WRITE, -}; - -struct opkg_opk_gzip { - enum _opkg_opk_gzip_dir dir; - opkg_opk_gzip_read_func *read_func; - void *user_data; - FILE *write_fp; - char write_buffer[512]; - size_t written; - z_stream stream; - gz_header gz_header; -}; - -struct opkg_opk_gzip * -opkg_opk_gzip_init_read(opkg_opk_gzip_read_func *read_func, void *user_data) -{ - struct opkg_opk_gzip *gzip; - - gzip = malloc(sizeof(*gzip)); - if (gzip == NULL) { - return NULL; - } - - gzip->dir = _OPKG_OPK_GZIP_DIR_READ; - gzip->read_func = read_func; - gzip->user_data = user_data; - - gzip->stream.zalloc = Z_NULL; - gzip->stream.zfree = Z_NULL; - gzip->stream.opaque = Z_NULL; - - gzip->stream.next_in = Z_NULL; - gzip->stream.avail_in = 0; - if (inflateInit2(&gzip->stream, OPKG_OPK_GZIP_WINDOW_BITS_) != Z_OK) { - free(gzip); - return NULL; - } - - return gzip; -} - -struct opkg_opk_gzip * -opkg_opk_gzip_init_write(FILE *write_fp) -{ - struct opkg_opk_gzip *gzip; - - gzip = malloc(sizeof(*gzip)); - if (gzip == NULL) { - return NULL; - } - - gzip->dir = _OPKG_OPK_GZIP_DIR_WRITE; - gzip->write_fp = write_fp; - gzip->written = 0; - - gzip->stream.zalloc = Z_NULL; - gzip->stream.zfree = Z_NULL; - gzip->stream.opaque = Z_NULL; - - gzip->stream.next_out = Z_NULL; - gzip->stream.avail_out = 0; - if (deflateInit2(&gzip->stream, 9, Z_DEFLATED, - OPKG_OPK_GZIP_WINDOW_BITS_, 9, - Z_DEFAULT_STRATEGY) != Z_OK) { - free(gzip); - return NULL; - } - gzip->gz_header.text = 0; - gzip->gz_header.time = 0; /* Stored as 32-bit uint */ - gzip->gz_header.os = 3; /* Unix, per RFC 1952 */ - gzip->gz_header.extra = Z_NULL; - gzip->gz_header.name = Z_NULL; - gzip->gz_header.comment = Z_NULL; - gzip->gz_header.hcrc = 0; - if (deflateSetHeader(&gzip->stream, &gzip->gz_header) != Z_OK) { - deflateEnd(&gzip->stream); - free(gzip); - return NULL; - } - - return gzip; -} - -int -opkg_opk_gzip_read(struct opkg_opk_gzip *gzip, void *record) -{ - int end; - - /* Sanity check */ - if (gzip->dir != _OPKG_OPK_GZIP_DIR_READ) { - return OPKG_OPK_ERROR; - } - - gzip->stream.next_out = record; - gzip->stream.avail_out = OPKG_OPK_USTAR_RECORD_SIZE; - - for (;;) { - end = 0; - if (gzip->stream.avail_in == 0) { - /* Input buffer is empty and needs refilled. */ - switch (gzip->read_func(gzip->user_data, - (char **) &gzip->stream.next_in, - (size_t *) &gzip->stream. - avail_in)) { - case OPKG_OPK_OK: - break; - case OPKG_OPK_END: - end = 1; - break; - case OPKG_OPK_ERROR: - default: - return OPKG_OPK_ERROR; - } - } - switch (inflate(&gzip->stream, Z_SYNC_FLUSH)) { - case Z_OK: - break; - case Z_BUF_ERROR: - if (end == 1) { - return OPKG_OPK_ERROR; - } - break; - case Z_STREAM_END: - if (gzip->stream.avail_out != 0) { - /* Premature end */ - return OPKG_OPK_ERROR; - } - return OPKG_OPK_END; - default: - return OPKG_OPK_ERROR; - } - if (gzip->stream.avail_out == 0) { - /* Output buffer is filled and ready for use. */ - return OPKG_OPK_OK; - } - } -} - -static int -_opkg_opk_gzip_write(struct opkg_opk_gzip *gzip, void *record, size_t size, - int last) -{ - size_t len; - - /* Sanity check */ - if (gzip->dir != _OPKG_OPK_GZIP_DIR_WRITE) { - return OPKG_OPK_ERROR; - } - - gzip->stream.next_in = record; - gzip->stream.avail_in = size; - - do { - gzip->stream.next_out = gzip->write_buffer; - gzip->stream.avail_out = sizeof(gzip->write_buffer); - switch (deflate(&gzip->stream, - (last > 0 ? Z_FINISH : Z_NO_FLUSH))) { - case Z_OK: - case Z_BUF_ERROR: - case Z_STREAM_END: - break; - default: - return OPKG_OPK_ERROR; - } - /* Process output buffer. */ - len = sizeof(gzip->write_buffer) - gzip->stream.avail_out; - if (fwrite(gzip->write_buffer, 1, len, gzip->write_fp) != len) { - return OPKG_OPK_ERROR; - } - gzip->written += len; - } while (gzip->stream.avail_out == 0); - - if (gzip->stream.avail_in != 0) { - return OPKG_OPK_ERROR; - } - if (last == 0) { - /* Input buffer is empty and needs refilled. */ - return OPKG_OPK_OK; - } else { - return OPKG_OPK_END; - } -} - -int -opkg_opk_gzip_write(struct opkg_opk_gzip *gzip, void *record, size_t size) -{ - if (_opkg_opk_gzip_write(gzip, record, size, 0) == OPKG_OPK_OK) { - return OPKG_OPK_OK; - } else { - return OPKG_OPK_ERROR; - } -} - -size_t -opkg_opk_gzip_written(struct opkg_opk_gzip *gzip) -{ - return gzip->written; -} - -int -opkg_opk_gzip_finish_write(struct opkg_opk_gzip *gzip) -{ - /* Sanity check */ - if (gzip->dir != _OPKG_OPK_GZIP_DIR_WRITE) { - return OPKG_OPK_ERROR; - } - - if (gzip->written > 0 && _opkg_opk_gzip_write(gzip, NULL, 0, 1) != - OPKG_OPK_END) { - return OPKG_OPK_ERROR; - } - return OPKG_OPK_OK; -} - -int -opkg_opk_gzip_free(struct opkg_opk_gzip *gzip) -{ - int ret; - - ret = OPKG_OPK_OK; - if (gzip->dir == _OPKG_OPK_GZIP_DIR_READ) { - if (inflateEnd(&gzip->stream) != Z_OK) { - ret = OPKG_OPK_ERROR; - } - } else { - if (deflateEnd(&gzip->stream) != Z_OK) { - ret = OPKG_OPK_ERROR; - } - } - free(gzip); - return ret; -} |