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]
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.
36 #include <sys/types.h>
43 #include <sys/filio.h>
44 #include <sys/fs/decomp.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
;
63 main(int argc
, char **argv
)
68 size_t blksize
= 8192;
71 while ((c
= getopt(argc
, argv
, "mcdb:")) != -1) {
78 (void) fprintf(stderr
, OPT_DC_EXCL
);
85 (void) fprintf(stderr
, OPT_DC_EXCL
);
91 blksize
= atoi(optarg
);
92 if (blksize
== 0 || (blksize
& (blksize
-1))) {
93 (void) fprintf(stderr
, INVALID_BLKSZ
);
98 (void) fprintf(stderr
, UNKNOWN_OPTION
, optopt
);
102 if (argc
- optind
!= 2) {
103 (void) fprintf(stderr
, MISS_FILES
);
107 setup_infile(argv
[optind
]);
108 setup_outfile(argv
[optind
+ 1]);
115 if (ioctl(dstfd
, _FIO_COMPRESSED
, 0) == -1) {
116 (void) fprintf(stderr
, FIO_COMP_FAIL
,
117 dstfile
, strerror(errno
));
126 setup_infile(char *file
)
134 fd
= open(srcfile
, O_RDONLY
, 0);
136 (void) fprintf(stderr
, CANT_OPEN
,
137 srcfile
, strerror(errno
));
141 if (fstat(fd
, &stbuf
) == -1) {
142 (void) fprintf(stderr
, STAT_FAIL
,
143 srcfile
, strerror(errno
));
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
));
157 setup_outfile(char *file
)
163 fd
= open(dstfile
, O_WRONLY
| O_CREAT
| O_TRUNC
,
164 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
);
166 (void) fprintf(stderr
, OPEN_FAIL
, dstfile
, strerror(errno
));
173 do_comp(size_t blksize
)
177 size_t blks
, dstlen
, hlen
;
181 blks
= ((srclen
- 1) / blksize
) + 1;
182 hlen
= offset
= sizeof (struct comphdr
) + blks
* sizeof (uint64_t);
185 (void) fprintf(stderr
, HDR_ALLOC
, hlen
);
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
);
202 if (lseek(dstfd
, offset
, SEEK_SET
) == (off_t
)-1) {
203 (void) fprintf(stderr
, SEEK_ERR
,
204 offset
, dstfile
, strerror(errno
));
208 for (i
= 0; i
< blks
; i
++) {
212 hdr
->ch_blkmap
[i
] = offset
;
213 slen
= MIN(srclen
, blksize
);
215 ret
= compress2(dstbuf
, &dlen
, (Bytef
*)srcaddr
, slen
, 9);
217 (void) fprintf(stderr
, COMP_ERR
, srcfile
, ret
);
221 if (write(dstfd
, dstbuf
, dlen
) != dlen
) {
222 (void) fprintf(stderr
, WRITE_ERR
,
223 dlen
, dstfile
, strerror(errno
));
232 if (lseek(dstfd
, 0, SEEK_SET
) == (off_t
)-1) {
233 (void) fprintf(stderr
, SEEK_ERR
,
234 0, dstfile
, strerror(errno
));
238 if (write(dstfd
, hdr
, hlen
) != hlen
) {
239 (void) fprintf(stderr
, WRITE_ERR
,
240 hlen
, dstfile
, strerror(errno
));
249 size_t blks
, blksize
;
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
);
261 if (hdr
->ch_version
!= CH_VERSION
) {
262 (void) fprintf(stderr
, BAD_VERS
,
263 srcfile
, (uint64_t)hdr
->ch_version
, CH_VERSION
);
266 if (hdr
->ch_algorithm
!= CH_ALG_ZLIB
) {
267 (void) fprintf(stderr
, BAD_ALG
,
268 srcfile
, (uint64_t)hdr
->ch_algorithm
, CH_ALG_ZLIB
);
272 blksize
= hdr
->ch_blksize
;
273 dstbuf
= malloc(blksize
);
274 if (dstbuf
== NULL
) {
275 (void) fprintf(stderr
, HDR_ALLOC
, blksize
);
279 blks
= (hdr
->ch_fsize
- 1) / blksize
;
280 srcaddr
+= hdr
->ch_blkmap
[0];
281 for (i
= 0; i
< blks
; i
++) {
283 slen
= hdr
->ch_blkmap
[i
+ 1] - hdr
->ch_blkmap
[i
];
284 ret
= uncompress(dstbuf
, &dlen
, (Bytef
*)srcaddr
, slen
);
286 (void) fprintf(stderr
, DECOMP_ERR
, srcfile
, ret
);
290 if (dlen
!= blksize
) {
291 (void) fprintf(stderr
, CORRUPT
, srcfile
);
294 if (write(dstfd
, dstbuf
, dlen
) != dlen
) {
295 (void) fprintf(stderr
, WRITE_ERR
,
296 dlen
, dstfile
, strerror(errno
));
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
);
309 if (write(dstfd
, dstbuf
, dlen
) != dlen
) {
310 (void) fprintf(stderr
, WRITE_ERR
,
311 dlen
, dstfile
, strerror(errno
));