Contributors: 4
	  
        
          | Author | 
          Tokens | 
          Token Proportion | 
          Commits | 
          Commit Proportion | 
        
	  
	  
        
        
          | Namhyung Kim | 
          306 | 
          73.03% | 
          1 | 
          12.50% | 
        
        
          | Jiri Olsa | 
          102 | 
          24.34% | 
          2 | 
          25.00% | 
        
        
          | Arnaldo Carvalho de Melo | 
          10 | 
          2.39% | 
          4 | 
          50.00% | 
        
        
          | Greg Kroah-Hartman | 
          1 | 
          0.24% | 
          1 | 
          12.50% | 
        
	  
	  
        
          | Total | 
          419 | 
           | 
          8 | 
           | 
	    
	  
    
 
// SPDX-License-Identifier: GPL-2.0
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <zlib.h>
#include <linux/compiler.h>
#include <internal/lib.h>
#include "util/compress.h"
#define CHUNK_SIZE  16384
int gzip_decompress_to_file(const char *input, int output_fd)
{
	int ret = Z_STREAM_ERROR;
	int input_fd;
	void *ptr;
	int len;
	struct stat stbuf;
	unsigned char buf[CHUNK_SIZE];
	z_stream zs = {
		.zalloc		= Z_NULL,
		.zfree		= Z_NULL,
		.opaque		= Z_NULL,
		.avail_in	= 0,
		.next_in	= Z_NULL,
	};
	input_fd = open(input, O_RDONLY);
	if (input_fd < 0)
		return -1;
	if (fstat(input_fd, &stbuf) < 0)
		goto out_close;
	ptr = mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, input_fd, 0);
	if (ptr == MAP_FAILED)
		goto out_close;
	if (inflateInit2(&zs, 16 + MAX_WBITS) != Z_OK)
		goto out_unmap;
	zs.next_in = ptr;
	zs.avail_in = stbuf.st_size;
	do {
		zs.next_out = buf;
		zs.avail_out = CHUNK_SIZE;
		ret = inflate(&zs, Z_NO_FLUSH);
		switch (ret) {
		case Z_NEED_DICT:
			ret = Z_DATA_ERROR;
			/* fall through */
		case Z_DATA_ERROR:
		case Z_MEM_ERROR:
			goto out;
		default:
			break;
		}
		len = CHUNK_SIZE - zs.avail_out;
		if (writen(output_fd, buf, len) != len) {
			ret = Z_DATA_ERROR;
			goto out;
		}
	} while (ret != Z_STREAM_END);
out:
	inflateEnd(&zs);
out_unmap:
	munmap(ptr, stbuf.st_size);
out_close:
	close(input_fd);
	return ret == Z_STREAM_END ? 0 : -1;
}
bool gzip_is_compressed(const char *input)
{
	int fd = open(input, O_RDONLY);
	const uint8_t magic[2] = { 0x1f, 0x8b };
	char buf[2] = { 0 };
	ssize_t rc;
	if (fd < 0)
		return -1;
	rc = read(fd, buf, sizeof(buf));
	close(fd);
	return rc == sizeof(buf) ?
	       memcmp(buf, magic, sizeof(buf)) == 0 : false;
}