1 5648 setje /* 2 5648 setje * CDDL HEADER START 3 5648 setje * 4 5648 setje * The contents of this file are subject to the terms of the 5 5648 setje * Common Development and Distribution License (the "License"). 6 5648 setje * You may not use this file except in compliance with the License. 7 5648 setje * 8 5648 setje * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 5648 setje * or http://www.opensolaris.org/os/licensing. 10 5648 setje * See the License for the specific language governing permissions 11 5648 setje * and limitations under the License. 12 5648 setje * 13 5648 setje * When distributing Covered Code, include this CDDL HEADER in each 14 5648 setje * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 5648 setje * If applicable, add the following below this CDDL HEADER, with the 16 5648 setje * fields enclosed by brackets "[]" replaced with your own identifying 17 5648 setje * information: Portions Copyright [yyyy] [name of copyright owner] 18 5648 setje * 19 5648 setje * CDDL HEADER END 20 5648 setje */ 21 5648 setje /* 22 7858 Krishnendu * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 5648 setje * Use is subject to license terms. 24 5648 setje */ 25 5648 setje 26 5648 setje /* 27 5648 setje * fiocompress - a utility to compress files with a filesystem. 28 5648 setje * Used to build compressed boot archives to reduce memory 29 5648 setje * requirements for booting. 30 5648 setje */ 31 5648 setje 32 5648 setje #include <stdio.h> 33 5648 setje #include <errno.h> 34 5648 setje #include <stdlib.h> 35 5648 setje #include <fcntl.h> 36 5648 setje #include <sys/types.h> 37 5648 setje #include <sys/stat.h> 38 5648 setje #include <sys/mman.h> 39 5648 setje #include <unistd.h> 40 5648 setje #include <utility.h> 41 5648 setje #include <zlib.h> 42 5648 setje 43 5648 setje #include <sys/filio.h> 44 5648 setje #include <sys/fs/decomp.h> 45 5648 setje 46 5648 setje #include "message.h" 47 5648 setje 48 5648 setje static void setup_infile(char *); 49 5648 setje static void setup_outfile(char *); 50 5648 setje static void do_comp(size_t); 51 5648 setje static void do_decomp(void); 52 5648 setje 53 5648 setje static caddr_t srcaddr; 54 5648 setje static size_t srclen; 55 5648 setje 56 5648 setje static int dstfd; 57 5648 setje 58 5648 setje static char *srcfile; 59 5648 setje static char *dstfile; 60 5648 setje 61 5648 setje 62 5648 setje int 63 5648 setje main(int argc, char **argv) 64 5648 setje { 65 5648 setje int compress = 0; 66 5648 setje int decompress = 0; 67 5648 setje int doioc = 0; 68 5648 setje size_t blksize = 8192; 69 5648 setje char c; 70 5648 setje 71 5648 setje while ((c = getopt(argc, argv, "mcdb:")) != -1) { 72 5648 setje switch (c) { 73 5648 setje case 'm': 74 5648 setje doioc++; 75 5648 setje break; 76 5648 setje case 'c': 77 5648 setje if (decompress) { 78 5648 setje (void) fprintf(stderr, OPT_DC_EXCL); 79 5648 setje exit(-1); 80 5648 setje } 81 5648 setje compress = 1; 82 5648 setje break; 83 5648 setje case 'd': 84 5648 setje if (compress) { 85 5648 setje (void) fprintf(stderr, OPT_DC_EXCL); 86 5648 setje exit(-1); 87 5648 setje } 88 5648 setje decompress = 1; 89 5648 setje break; 90 5648 setje case 'b': 91 5648 setje blksize = atoi(optarg); 92 5648 setje if (blksize == 0 || (blksize & (blksize-1))) { 93 5648 setje (void) fprintf(stderr, INVALID_BLKSZ); 94 5648 setje exit(-1); 95 5648 setje } 96 5648 setje break; 97 5648 setje case '?': 98 5648 setje (void) fprintf(stderr, UNKNOWN_OPTION, optopt); 99 5648 setje exit(-1); 100 5648 setje } 101 5648 setje } 102 5648 setje if (argc - optind != 2) { 103 5648 setje (void) fprintf(stderr, MISS_FILES); 104 5648 setje exit(-1); 105 5648 setje } 106 5648 setje 107 5648 setje setup_infile(argv[optind]); 108 5648 setje setup_outfile(argv[optind + 1]); 109 5648 setje 110 5648 setje if (decompress) 111 5648 setje do_decomp(); 112 5648 setje else { 113 5648 setje do_comp(blksize); 114 5648 setje if (doioc) { 115 5648 setje if (ioctl(dstfd, _FIO_COMPRESSED, 0) == -1) { 116 5648 setje (void) fprintf(stderr, FIO_COMP_FAIL, 117 5648 setje dstfile, strerror(errno)); 118 5648 setje exit(-1); 119 5648 setje } 120 5648 setje } 121 5648 setje } 122 5648 setje return (0); 123 5648 setje } 124 5648 setje 125 5648 setje static void 126 5648 setje setup_infile(char *file) 127 5648 setje { 128 5648 setje int fd; 129 5648 setje void *addr; 130 5648 setje struct stat stbuf; 131 5648 setje 132 5648 setje srcfile = file; 133 5648 setje 134 5648 setje fd = open(srcfile, O_RDONLY, 0); 135 5648 setje if (fd == -1) { 136 5648 setje (void) fprintf(stderr, CANT_OPEN, 137 5648 setje srcfile, strerror(errno)); 138 5648 setje exit(-1); 139 5648 setje } 140 5648 setje 141 5648 setje if (fstat(fd, &stbuf) == -1) { 142 5648 setje (void) fprintf(stderr, STAT_FAIL, 143 5648 setje srcfile, strerror(errno)); 144 5648 setje exit(-1); 145 5648 setje } 146 5648 setje srclen = stbuf.st_size; 147 5648 setje 148 5648 setje addr = mmap(0, srclen, PROT_READ, MAP_SHARED, fd, 0); 149 5648 setje if (addr == MAP_FAILED) { 150 5648 setje (void) fprintf(stderr, MMAP_FAIL, srcfile, strerror(errno)); 151 5648 setje exit(-1); 152 5648 setje } 153 5648 setje srcaddr = addr; 154 5648 setje } 155 5648 setje 156 5648 setje static void 157 5648 setje setup_outfile(char *file) 158 5648 setje { 159 5648 setje int fd; 160 5648 setje 161 5648 setje dstfile = file; 162 5648 setje 163 5648 setje fd = open(dstfile, O_WRONLY | O_CREAT | O_TRUNC, 164 5648 setje S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 165 5648 setje if (fd == -1) { 166 5648 setje (void) fprintf(stderr, OPEN_FAIL, dstfile, strerror(errno)); 167 5648 setje exit(-1); 168 5648 setje } 169 5648 setje dstfd = fd; 170 5648 setje } 171 5648 setje 172 5648 setje static void 173 5648 setje do_comp(size_t blksize) 174 5648 setje { 175 5648 setje struct comphdr *hdr; 176 5648 setje off_t offset; 177 5648 setje size_t blks, dstlen, hlen; 178 5648 setje void *dstbuf; 179 5648 setje int i; 180 5648 setje 181 5648 setje blks = ((srclen - 1) / blksize) + 1; 182 5648 setje hlen = offset = sizeof (struct comphdr) + blks * sizeof (uint64_t); 183 5648 setje hdr = malloc(hlen); 184 5648 setje if (hdr == NULL) { 185 5648 setje (void) fprintf(stderr, HDR_ALLOC, hlen); 186 5648 setje exit(-1); 187 5648 setje } 188 5648 setje 189 7858 Krishnendu hdr->ch_magic = CH_MAGIC_ZLIB; 190 5648 setje hdr->ch_version = CH_VERSION; 191 5648 setje hdr->ch_algorithm = CH_ALG_ZLIB; 192 5648 setje hdr->ch_fsize = srclen; 193 5648 setje hdr->ch_blksize = blksize; 194 5648 setje 195 5648 setje dstlen = ZMAXBUF(blksize); 196 5648 setje dstbuf = malloc(dstlen); 197 5648 setje if (dstbuf == NULL) { 198 5648 setje (void) fprintf(stderr, BUF_ALLOC, dstlen); 199 5648 setje exit(-1); 200 5648 setje } 201 5648 setje 202 5648 setje if (lseek(dstfd, offset, SEEK_SET) == (off_t)-1) { 203 5648 setje (void) fprintf(stderr, SEEK_ERR, 204 5648 setje offset, dstfile, strerror(errno)); 205 5648 setje exit(-1); 206 5648 setje } 207 5648 setje 208 5648 setje for (i = 0; i < blks; i++) { 209 5648 setje ulong_t slen, dlen; 210 5648 setje int ret; 211 5648 setje 212 5648 setje hdr->ch_blkmap[i] = offset; 213 5648 setje slen = MIN(srclen, blksize); 214 5648 setje dlen = dstlen; 215 5648 setje ret = compress2(dstbuf, &dlen, (Bytef *)srcaddr, slen, 9); 216 5648 setje if (ret != Z_OK) { 217 5648 setje (void) fprintf(stderr, COMP_ERR, srcfile, ret); 218 5648 setje exit(-1); 219 5648 setje } 220 5648 setje 221 5648 setje if (write(dstfd, dstbuf, dlen) != dlen) { 222 5648 setje (void) fprintf(stderr, WRITE_ERR, 223 5648 setje dlen, dstfile, strerror(errno)); 224 5648 setje exit(-1); 225 5648 setje } 226 5648 setje 227 5648 setje offset += dlen; 228 5648 setje srclen -= slen; 229 5648 setje srcaddr += slen; 230 5648 setje } 231 5648 setje 232 5648 setje if (lseek(dstfd, 0, SEEK_SET) == (off_t)-1) { 233 5648 setje (void) fprintf(stderr, SEEK_ERR, 234 5648 setje 0, dstfile, strerror(errno)); 235 5648 setje exit(-1); 236 5648 setje } 237 5648 setje 238 5648 setje if (write(dstfd, hdr, hlen) != hlen) { 239 5648 setje (void) fprintf(stderr, WRITE_ERR, 240 5648 setje hlen, dstfile, strerror(errno)); 241 5648 setje exit(-1); 242 5648 setje } 243 5648 setje } 244 5648 setje 245 5648 setje static void 246 5648 setje do_decomp() 247 5648 setje { 248 5648 setje struct comphdr *hdr; 249 5648 setje size_t blks, blksize; 250 5648 setje void *dstbuf; 251 5648 setje int i; 252 5648 setje ulong_t slen, dlen; 253 5648 setje int ret; 254 5648 setje 255 5648 setje hdr = (struct comphdr *)(void *)srcaddr; 256 7858 Krishnendu if (hdr->ch_magic != CH_MAGIC_ZLIB) { 257 5648 setje (void) fprintf(stderr, BAD_MAGIC, 258 7858 Krishnendu srcfile, (uint64_t)hdr->ch_magic, CH_MAGIC_ZLIB); 259 5648 setje exit(-1); 260 5648 setje } 261 5648 setje if (hdr->ch_version != CH_VERSION) { 262 5648 setje (void) fprintf(stderr, BAD_VERS, 263 5648 setje srcfile, (uint64_t)hdr->ch_version, CH_VERSION); 264 5648 setje exit(-1); 265 5648 setje } 266 5648 setje if (hdr->ch_algorithm != CH_ALG_ZLIB) { 267 5648 setje (void) fprintf(stderr, BAD_ALG, 268 5648 setje srcfile, (uint64_t)hdr->ch_algorithm, CH_ALG_ZLIB); 269 5648 setje exit(-1); 270 5648 setje } 271 5648 setje 272 5648 setje blksize = hdr->ch_blksize; 273 5648 setje dstbuf = malloc(blksize); 274 5648 setje if (dstbuf == NULL) { 275 5648 setje (void) fprintf(stderr, HDR_ALLOC, blksize); 276 5648 setje exit(-1); 277 5648 setje } 278 5648 setje 279 5648 setje blks = (hdr->ch_fsize - 1) / blksize; 280 5648 setje srcaddr += hdr->ch_blkmap[0]; 281 5648 setje for (i = 0; i < blks; i++) { 282 5648 setje dlen = blksize; 283 5648 setje slen = hdr->ch_blkmap[i + 1] - hdr->ch_blkmap[i]; 284 5648 setje ret = uncompress(dstbuf, &dlen, (Bytef *)srcaddr, slen); 285 5648 setje if (ret != Z_OK) { 286 5648 setje (void) fprintf(stderr, DECOMP_ERR, srcfile, ret); 287 5648 setje exit(-1); 288 5648 setje } 289 5648 setje 290 5648 setje if (dlen != blksize) { 291 5648 setje (void) fprintf(stderr, CORRUPT, srcfile); 292 5648 setje exit(-1); 293 5648 setje } 294 5648 setje if (write(dstfd, dstbuf, dlen) != dlen) { 295 5648 setje (void) fprintf(stderr, WRITE_ERR, 296 5648 setje dlen, dstfile, strerror(errno)); 297 5648 setje exit(-1); 298 5648 setje } 299 5648 setje srcaddr += slen; 300 5648 setje } 301 5648 setje 302 5648 setje dlen = blksize; 303 5648 setje slen = hdr->ch_fsize - hdr->ch_blkmap[i]; 304 5648 setje if ((ret = uncompress(dstbuf, &dlen, (Bytef *)srcaddr, slen)) != Z_OK) { 305 5648 setje (void) fprintf(stderr, DECOMP_ERR, dstfile, ret); 306 5648 setje exit(-1); 307 5648 setje } 308 5648 setje 309 5648 setje if (write(dstfd, dstbuf, dlen) != dlen) { 310 5648 setje (void) fprintf(stderr, WRITE_ERR, 311 5648 setje dlen, dstfile, strerror(errno)); 312 5648 setje exit(-1); 313 5648 setje } 314 5648 setje } 315