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