brintos

brintos / linux-shallow public Read only

0
0
Text · 1.8 KiB · 78d2297 Raw
98 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <fcntl.h>3#include <stdio.h>4#include <string.h>5#include <unistd.h>6#include <sys/stat.h>7#include <sys/mman.h>8#include <zlib.h>9#include <linux/compiler.h>10#include <internal/lib.h>11 12#include "util/compress.h"13 14#define CHUNK_SIZE  1638415 16int gzip_decompress_to_file(const char *input, int output_fd)17{18	int ret = Z_STREAM_ERROR;19	int input_fd;20	void *ptr;21	int len;22	struct stat stbuf;23	unsigned char buf[CHUNK_SIZE];24	z_stream zs = {25		.zalloc		= Z_NULL,26		.zfree		= Z_NULL,27		.opaque		= Z_NULL,28		.avail_in	= 0,29		.next_in	= Z_NULL,30	};31 32	input_fd = open(input, O_RDONLY);33	if (input_fd < 0)34		return -1;35 36	if (fstat(input_fd, &stbuf) < 0)37		goto out_close;38 39	ptr = mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, input_fd, 0);40	if (ptr == MAP_FAILED)41		goto out_close;42 43	if (inflateInit2(&zs, 16 + MAX_WBITS) != Z_OK)44		goto out_unmap;45 46	zs.next_in = ptr;47	zs.avail_in = stbuf.st_size;48 49	do {50		zs.next_out = buf;51		zs.avail_out = CHUNK_SIZE;52 53		ret = inflate(&zs, Z_NO_FLUSH);54		switch (ret) {55		case Z_NEED_DICT:56			ret = Z_DATA_ERROR;57			/* fall through */58		case Z_DATA_ERROR:59		case Z_MEM_ERROR:60			goto out;61		default:62			break;63		}64 65		len = CHUNK_SIZE - zs.avail_out;66		if (writen(output_fd, buf, len) != len) {67			ret = Z_DATA_ERROR;68			goto out;69		}70 71	} while (ret != Z_STREAM_END);72 73out:74	inflateEnd(&zs);75out_unmap:76	munmap(ptr, stbuf.st_size);77out_close:78	close(input_fd);79 80	return ret == Z_STREAM_END ? 0 : -1;81}82 83bool gzip_is_compressed(const char *input)84{85	int fd = open(input, O_RDONLY);86	const uint8_t magic[2] = { 0x1f, 0x8b };87	char buf[2] = { 0 };88	ssize_t rc;89 90	if (fd < 0)91		return -1;92 93	rc = read(fd, buf, sizeof(buf));94	close(fd);95	return rc == sizeof(buf) ?96	       memcmp(buf, magic, sizeof(buf)) == 0 : false;97}98