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>
41 #include <sys/filio.h>
42 #include <sys/fs/decomp.h>
47 #define MIN(x, y) ((x) < (y) ? (x) : (y))
49 static void setup_infile(char *);
50 static void setup_outfile(char *);
51 static void do_comp(size_t);
52 static void do_decomp(void);
54 static caddr_t srcaddr
;
64 main(int argc
, char **argv
)
69 size_t blksize
= 8192;
72 while ((c
= getopt(argc
, argv
, "mcdb:")) != -1) {
79 (void) fprintf(stderr
, OPT_DC_EXCL
);
86 (void) fprintf(stderr
, OPT_DC_EXCL
);
92 blksize
= atoi(optarg
);
93 if (blksize
== 0 || (blksize
& (blksize
-1))) {
94 (void) fprintf(stderr
, INVALID_BLKSZ
);
99 (void) fprintf(stderr
, UNKNOWN_OPTION
, optopt
);
103 if (argc
- optind
!= 2) {
104 (void) fprintf(stderr
, MISS_FILES
);
108 setup_infile(argv
[optind
]);
109 setup_outfile(argv
[optind
+ 1]);
116 if (ioctl(dstfd
, _FIO_COMPRESSED
, 0) == -1) {
117 (void) fprintf(stderr
, FIO_COMP_FAIL
,
118 dstfile
, strerror(errno
));
127 setup_infile(char *file
)
135 fd
= open(srcfile
, O_RDONLY
, 0);
137 (void) fprintf(stderr
, CANT_OPEN
,
138 srcfile
, strerror(errno
));
142 if (fstat(fd
, &stbuf
) == -1) {
143 (void) fprintf(stderr
, STAT_FAIL
,
144 srcfile
, strerror(errno
));
147 srclen
= stbuf
.st_size
;
149 addr
= mmap(NULL
, srclen
, PROT_READ
, MAP_SHARED
, fd
, 0);
150 if (addr
== MAP_FAILED
) {
151 (void) fprintf(stderr
, MMAP_FAIL
, srcfile
, strerror(errno
));
158 setup_outfile(char *file
)
164 fd
= open(dstfile
, O_WRONLY
| O_CREAT
| O_TRUNC
,
165 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
);
167 (void) fprintf(stderr
, OPEN_FAIL
, dstfile
, strerror(errno
));
174 do_comp(size_t blksize
)
178 size_t blks
, dstlen
, hlen
;
182 blks
= ((srclen
- 1) / blksize
) + 1;
183 hlen
= offset
= sizeof (struct comphdr
) + blks
* sizeof (uint64_t);
186 (void) fprintf(stderr
, HDR_ALLOC
, hlen
);
190 hdr
->ch_magic
= CH_MAGIC_ZLIB
;
191 hdr
->ch_version
= CH_VERSION
;
192 hdr
->ch_algorithm
= CH_ALG_ZLIB
;
193 hdr
->ch_fsize
= srclen
;
194 hdr
->ch_blksize
= blksize
;
196 dstlen
= ZMAXBUF(blksize
);
197 dstbuf
= malloc(dstlen
);
198 if (dstbuf
== NULL
) {
199 (void) fprintf(stderr
, BUF_ALLOC
, dstlen
);
203 if (lseek(dstfd
, offset
, SEEK_SET
) == (off_t
)-1) {
204 (void) fprintf(stderr
, SEEK_ERR
,
205 offset
, dstfile
, strerror(errno
));
209 for (i
= 0; i
< blks
; i
++) {
213 hdr
->ch_blkmap
[i
] = offset
;
214 slen
= MIN(srclen
, blksize
);
216 ret
= compress2(dstbuf
, &dlen
, (Bytef
*)srcaddr
, slen
, 9);
218 (void) fprintf(stderr
, COMP_ERR
, srcfile
, ret
);
222 if (write(dstfd
, dstbuf
, dlen
) != dlen
) {
223 (void) fprintf(stderr
, WRITE_ERR
,
224 dlen
, dstfile
, strerror(errno
));
233 if (lseek(dstfd
, 0, SEEK_SET
) == (off_t
)-1) {
234 (void) fprintf(stderr
, SEEK_ERR
,
235 0, dstfile
, strerror(errno
));
239 if (write(dstfd
, hdr
, hlen
) != hlen
) {
240 (void) fprintf(stderr
, WRITE_ERR
,
241 hlen
, dstfile
, strerror(errno
));
250 size_t blks
, blksize
;
256 hdr
= (struct comphdr
*)(void *)srcaddr
;
257 if (hdr
->ch_magic
!= CH_MAGIC_ZLIB
) {
258 (void) fprintf(stderr
, BAD_MAGIC
,
259 srcfile
, (uint64_t)hdr
->ch_magic
, CH_MAGIC_ZLIB
);
262 if (hdr
->ch_version
!= CH_VERSION
) {
263 (void) fprintf(stderr
, BAD_VERS
,
264 srcfile
, (uint64_t)hdr
->ch_version
, CH_VERSION
);
267 if (hdr
->ch_algorithm
!= CH_ALG_ZLIB
) {
268 (void) fprintf(stderr
, BAD_ALG
,
269 srcfile
, (uint64_t)hdr
->ch_algorithm
, CH_ALG_ZLIB
);
273 blksize
= hdr
->ch_blksize
;
274 dstbuf
= malloc(blksize
);
275 if (dstbuf
== NULL
) {
276 (void) fprintf(stderr
, HDR_ALLOC
, blksize
);
280 blks
= (hdr
->ch_fsize
- 1) / blksize
;
281 srcaddr
+= hdr
->ch_blkmap
[0];
282 for (i
= 0; i
< blks
; i
++) {
284 slen
= hdr
->ch_blkmap
[i
+ 1] - hdr
->ch_blkmap
[i
];
285 ret
= uncompress(dstbuf
, &dlen
, (Bytef
*)srcaddr
, slen
);
287 (void) fprintf(stderr
, DECOMP_ERR
, srcfile
, ret
);
291 if (dlen
!= blksize
) {
292 (void) fprintf(stderr
, CORRUPT
, srcfile
);
295 if (write(dstfd
, dstbuf
, dlen
) != dlen
) {
296 (void) fprintf(stderr
, WRITE_ERR
,
297 dlen
, dstfile
, strerror(errno
));
304 slen
= hdr
->ch_fsize
- hdr
->ch_blkmap
[i
];
305 if ((ret
= uncompress(dstbuf
, &dlen
, (Bytef
*)srcaddr
, slen
)) != Z_OK
) {
306 (void) fprintf(stderr
, DECOMP_ERR
, dstfile
, ret
);
310 if (write(dstfd
, dstbuf
, dlen
) != dlen
) {
311 (void) fprintf(stderr
, WRITE_ERR
,
312 dlen
, dstfile
, strerror(errno
));