986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje/*
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje * CDDL HEADER START
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje *
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje * The contents of this file are subject to the terms of the
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje * Common Development and Distribution License (the "License").
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje * You may not use this file except in compliance with the License.
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje *
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje * or http://www.opensolaris.org/os/licensing.
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje * See the License for the specific language governing permissions
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje * and limitations under the License.
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje *
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje * When distributing Covered Code, include this CDDL HEADER in each
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje * If applicable, add the following below this CDDL HEADER, with the
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje * fields enclosed by brackets "[]" replaced with your own identifying
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje * information: Portions Copyright [yyyy] [name of copyright owner]
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje *
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje * CDDL HEADER END
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje */
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje/*
1d7f3fadeebf3754e3f042d91e7a4439755dc598Krishnendu Sadhukhan - Sun Microsystems * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje * Use is subject to license terms.
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje */
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje/*
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje * fiocompress - a utility to compress files with a filesystem.
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje * Used to build compressed boot archives to reduce memory
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje * requirements for booting.
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje */
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje#include <stdio.h>
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje#include <errno.h>
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje#include <stdlib.h>
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje#include <fcntl.h>
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje#include <sys/types.h>
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje#include <sys/stat.h>
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje#include <sys/mman.h>
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje#include <unistd.h>
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje#include <utility.h>
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje#include <zlib.h>
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje#include <sys/filio.h>
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje#include <sys/fs/decomp.h>
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje#include "message.h"
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjestatic void setup_infile(char *);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjestatic void setup_outfile(char *);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjestatic void do_comp(size_t);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjestatic void do_decomp(void);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjestatic caddr_t srcaddr;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjestatic size_t srclen;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjestatic int dstfd;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjestatic char *srcfile;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjestatic char *dstfile;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjeint
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjemain(int argc, char **argv)
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje{
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje int compress = 0;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje int decompress = 0;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje int doioc = 0;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje size_t blksize = 8192;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje char c;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje while ((c = getopt(argc, argv, "mcdb:")) != -1) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje switch (c) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje case 'm':
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje doioc++;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje break;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje case 'c':
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (decompress) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, OPT_DC_EXCL);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje compress = 1;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje break;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje case 'd':
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (compress) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, OPT_DC_EXCL);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje decompress = 1;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje break;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje case 'b':
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje blksize = atoi(optarg);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (blksize == 0 || (blksize & (blksize-1))) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, INVALID_BLKSZ);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje break;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje case '?':
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, UNKNOWN_OPTION, optopt);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (argc - optind != 2) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, MISS_FILES);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje setup_infile(argv[optind]);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje setup_outfile(argv[optind + 1]);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (decompress)
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje do_decomp();
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje do_comp(blksize);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (doioc) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (ioctl(dstfd, _FIO_COMPRESSED, 0) == -1) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, FIO_COMP_FAIL,
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dstfile, strerror(errno));
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje return (0);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje}
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjestatic void
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjesetup_infile(char *file)
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje{
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje int fd;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje void *addr;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje struct stat stbuf;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje srcfile = file;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje fd = open(srcfile, O_RDONLY, 0);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (fd == -1) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, CANT_OPEN,
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje srcfile, strerror(errno));
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (fstat(fd, &stbuf) == -1) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, STAT_FAIL,
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje srcfile, strerror(errno));
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje srclen = stbuf.st_size;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje addr = mmap(0, srclen, PROT_READ, MAP_SHARED, fd, 0);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (addr == MAP_FAILED) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, MMAP_FAIL, srcfile, strerror(errno));
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje srcaddr = addr;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje}
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjestatic void
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjesetup_outfile(char *file)
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje{
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje int fd;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dstfile = file;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje fd = open(dstfile, O_WRONLY | O_CREAT | O_TRUNC,
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (fd == -1) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, OPEN_FAIL, dstfile, strerror(errno));
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dstfd = fd;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje}
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjestatic void
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjedo_comp(size_t blksize)
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje{
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje struct comphdr *hdr;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje off_t offset;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje size_t blks, dstlen, hlen;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje void *dstbuf;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje int i;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje blks = ((srclen - 1) / blksize) + 1;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje hlen = offset = sizeof (struct comphdr) + blks * sizeof (uint64_t);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje hdr = malloc(hlen);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (hdr == NULL) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, HDR_ALLOC, hlen);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
1d7f3fadeebf3754e3f042d91e7a4439755dc598Krishnendu Sadhukhan - Sun Microsystems hdr->ch_magic = CH_MAGIC_ZLIB;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje hdr->ch_version = CH_VERSION;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje hdr->ch_algorithm = CH_ALG_ZLIB;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje hdr->ch_fsize = srclen;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje hdr->ch_blksize = blksize;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dstlen = ZMAXBUF(blksize);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dstbuf = malloc(dstlen);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (dstbuf == NULL) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, BUF_ALLOC, dstlen);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (lseek(dstfd, offset, SEEK_SET) == (off_t)-1) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, SEEK_ERR,
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje offset, dstfile, strerror(errno));
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje for (i = 0; i < blks; i++) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ulong_t slen, dlen;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje int ret;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje hdr->ch_blkmap[i] = offset;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje slen = MIN(srclen, blksize);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dlen = dstlen;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ret = compress2(dstbuf, &dlen, (Bytef *)srcaddr, slen, 9);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (ret != Z_OK) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, COMP_ERR, srcfile, ret);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (write(dstfd, dstbuf, dlen) != dlen) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, WRITE_ERR,
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dlen, dstfile, strerror(errno));
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje offset += dlen;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje srclen -= slen;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje srcaddr += slen;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (lseek(dstfd, 0, SEEK_SET) == (off_t)-1) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, SEEK_ERR,
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0, dstfile, strerror(errno));
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (write(dstfd, hdr, hlen) != hlen) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, WRITE_ERR,
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje hlen, dstfile, strerror(errno));
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje}
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjestatic void
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjedo_decomp()
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje{
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje struct comphdr *hdr;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje size_t blks, blksize;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje void *dstbuf;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje int i;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ulong_t slen, dlen;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje int ret;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje hdr = (struct comphdr *)(void *)srcaddr;
1d7f3fadeebf3754e3f042d91e7a4439755dc598Krishnendu Sadhukhan - Sun Microsystems if (hdr->ch_magic != CH_MAGIC_ZLIB) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, BAD_MAGIC,
1d7f3fadeebf3754e3f042d91e7a4439755dc598Krishnendu Sadhukhan - Sun Microsystems srcfile, (uint64_t)hdr->ch_magic, CH_MAGIC_ZLIB);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (hdr->ch_version != CH_VERSION) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, BAD_VERS,
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje srcfile, (uint64_t)hdr->ch_version, CH_VERSION);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (hdr->ch_algorithm != CH_ALG_ZLIB) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, BAD_ALG,
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje srcfile, (uint64_t)hdr->ch_algorithm, CH_ALG_ZLIB);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje blksize = hdr->ch_blksize;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dstbuf = malloc(blksize);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (dstbuf == NULL) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, HDR_ALLOC, blksize);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje blks = (hdr->ch_fsize - 1) / blksize;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje srcaddr += hdr->ch_blkmap[0];
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje for (i = 0; i < blks; i++) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dlen = blksize;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje slen = hdr->ch_blkmap[i + 1] - hdr->ch_blkmap[i];
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ret = uncompress(dstbuf, &dlen, (Bytef *)srcaddr, slen);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (ret != Z_OK) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, DECOMP_ERR, srcfile, ret);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (dlen != blksize) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, CORRUPT, srcfile);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (write(dstfd, dstbuf, dlen) != dlen) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, WRITE_ERR,
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dlen, dstfile, strerror(errno));
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje srcaddr += slen;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dlen = blksize;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje slen = hdr->ch_fsize - hdr->ch_blkmap[i];
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if ((ret = uncompress(dstbuf, &dlen, (Bytef *)srcaddr, slen)) != Z_OK) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, DECOMP_ERR, dstfile, ret);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje if (write(dstfd, dstbuf, dlen) != dlen) {
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje (void) fprintf(stderr, WRITE_ERR,
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dlen, dstfile, strerror(errno));
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit(-1);
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje }
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje}