123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- /* $MirOS: contrib/hosted/fwcf/minilzop.c,v 1.2 2007/03/09 22:25:45 tg Exp $ */
- /*-
- * Copyright (c) 2007
- * Thorsten Glaser <tg@mirbsd.de>
- *
- * Provided that these terms and disclaimer and all copyright notices
- * are retained or reproduced in an accompanying document, permission
- * is granted to deal in this work without restriction, including un-
- * limited rights to use, publicly perform, distribute, sell, modify,
- * merge, give away, or sublicence.
- *
- * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
- * the utmost extent permitted by applicable law, neither express nor
- * implied; without malicious intent or gross negligence. In no event
- * may a licensor, author or contributor be held liable for indirect,
- * direct, other damage, loss, or other issues arising in any way out
- * of dealing in the work, even if advised of the possibility of such
- * damage or existence of a defect, except proven that it results out
- * of said person's immediate fault when using the work as intended.
- */
- #include <sys/param.h>
- #include <err.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include "defs.h"
- #include "adler.h"
- #include "compress.h"
- #include "minilzop.h"
- __RCSID("$MirOS: contrib/hosted/fwcf/minilzop.c,v 1.2 2007/03/09 22:25:45 tg Exp $");
- #define lodsw(s) __extension__({ \
- const uint8_t *lodsw_buf = (const uint8_t *)(s);\
- uint16_t lodsw_val; \
- \
- lodsw_val = lodsw_buf[0]; \
- lodsw_val |= lodsw_buf[1] << 8; \
- (lodsw_val); \
- })
- #define lodsd(s) __extension__({ \
- const uint8_t *lodsd_buf = (const uint8_t *)(s);\
- uint32_t lodsd_val; \
- \
- lodsd_val = lodsd_buf[0]; \
- lodsd_val |= lodsd_buf[1] << 8; \
- lodsd_val |= lodsd_buf[2] << 16; \
- lodsd_val |= lodsd_buf[3] << 24; \
- (lodsd_val); \
- })
- #define stosw(s,w) do { \
- uint8_t *stosw_buf = (uint8_t *)(s); \
- uint16_t stosw_val = (w); \
- \
- stosw_buf[0] = stosw_val & 0xFF; \
- stosw_buf[1] = (stosw_val >> 8) & 0xFF; \
- } while (0)
- #define stosd(s,dw) do { \
- uint8_t *stosd_buf = (uint8_t *)(s); \
- uint32_t stosd_val = (dw); \
- \
- stosd_buf[0] = stosd_val & 0xFF; \
- stosd_buf[1] = (stosd_val >> 8) & 0xFF; \
- stosd_buf[2] = (stosd_val >> 16) & 0xFF; \
- stosd_buf[3] = (stosd_val >> 24) & 0xFF; \
- } while (0)
- void
- read_aszdata(int dfd, char **dbuf, size_t *dlen)
- {
- size_t len;
- uint8_t hdrbuf[8];
- ADLER_DECL;
- if (read(dfd, hdrbuf, 8) != 8)
- err(1, "short read");
- *dlen = lodsd(hdrbuf + 4);
- if ((*dbuf = malloc(*dlen)) == NULL)
- err(255, "out of memory trying to allocate %zu bytes", *dlen);
- if ((size_t)read(dfd, *dbuf, *dlen) != *dlen)
- err(1, "short read");
- len = 4;
- ADLER_CALC(hdrbuf + 4);
- len = *dlen;
- ADLER_CALC(*dbuf);
- if ((lodsw(hdrbuf) != s1) || (lodsw(hdrbuf + 2) != s2))
- err(2, "checksum mismatch, size %zu,"
- " want 0x%02X%02X%02X%02X got 0x%04X%04X", *dlen,
- hdrbuf[3], hdrbuf[2], hdrbuf[1], hdrbuf[0], s2, s1);
- }
- void
- write_aszdata(int dfd, const char *dbuf, size_t dlen)
- {
- size_t len;
- uint8_t hdrbuf[8];
- ADLER_DECL;
- stosd(hdrbuf + 4, dlen);
- len = 4;
- ADLER_CALC(hdrbuf + 4);
- len = dlen;
- ADLER_CALC(dbuf);
- stosw(hdrbuf, s1);
- stosw(hdrbuf + 2, s2);
- if (write(dfd, hdrbuf, 8) != 8)
- err(1, "short write");
- if ((size_t)write(dfd, dbuf, dlen) != dlen)
- err(1, "short write");
- }
- int
- minilzop(int ifd, int ofd, int compr_alg, int decompress)
- {
- size_t ilen, olen, n;
- char *idata, *odata;
- #ifndef SMALL
- fprintf(stderr, "minilzop: using algorithm %02X (%s)\n",
- compr_alg, compressor_get(compr_alg)->name);
- #endif
- if (decompress) {
- read_aszdata(ifd, &idata, &ilen);
- olen = lodsd(idata);
- if ((odata = malloc(olen)) == NULL)
- err(255, "out of memory trying to allocate %zu bytes",
- olen);
- if ((n = compressor_get(compr_alg)->decompress(odata, olen,
- idata + 4, ilen - 4)) != olen)
- errx(1, "size mismatch: decompressed %zu, want %zu",
- n, olen);
- free(idata);
- idata = odata; /* save for later free(3) */
- while (olen) {
- if ((n = write(ofd, odata, olen)) == (size_t)-1)
- err(1, "cannot write");
- olen -= n;
- odata += n;
- }
- free(idata);
- } else {
- size_t cc;
- n = 16384;
- idata = NULL;
- ilen = 0;
- slurp_file:
- if ((idata = realloc(idata, (n <<= 1))) == NULL)
- err(255, "out of memory trying to allocate %zu bytes",
- n);
- slurp_retry:
- if ((cc = read(ifd, idata + ilen, n - ilen)) == (size_t)-1)
- err(1, "cannot read");
- ilen += cc;
- if (cc > 0) {
- if (ilen < n)
- goto slurp_retry;
- goto slurp_file;
- }
- if ((olen = compressor_get(compr_alg)->compress(&odata, idata,
- ilen)) == (size_t)-1)
- errx(1, "%s compression failed",
- compressor_get(compr_alg)->name);
- free(idata);
- if ((idata = malloc(olen + 4)) == NULL)
- err(255, "out of memory trying to allocate %zu bytes",
- olen + 4);
- stosd(idata, ilen);
- memcpy(idata + 4, odata, olen);
- write_aszdata(ofd, idata, olen + 4);
- free(idata);
- }
- return (0);
- }
|