minilzop.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /* $MirOS: contrib/hosted/fwcf/minilzop.c,v 1.2 2007/03/09 22:25:45 tg Exp $ */
  2. /*-
  3. * Copyright (c) 2007
  4. * Thorsten Glaser <tg@mirbsd.de>
  5. *
  6. * Provided that these terms and disclaimer and all copyright notices
  7. * are retained or reproduced in an accompanying document, permission
  8. * is granted to deal in this work without restriction, including un-
  9. * limited rights to use, publicly perform, distribute, sell, modify,
  10. * merge, give away, or sublicence.
  11. *
  12. * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
  13. * the utmost extent permitted by applicable law, neither express nor
  14. * implied; without malicious intent or gross negligence. In no event
  15. * may a licensor, author or contributor be held liable for indirect,
  16. * direct, other damage, loss, or other issues arising in any way out
  17. * of dealing in the work, even if advised of the possibility of such
  18. * damage or existence of a defect, except proven that it results out
  19. * of said person's immediate fault when using the work as intended.
  20. */
  21. #include <sys/param.h>
  22. #include <err.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <unistd.h>
  27. #include "defs.h"
  28. #include "adler.h"
  29. #include "compress.h"
  30. #include "minilzop.h"
  31. __RCSID("$MirOS: contrib/hosted/fwcf/minilzop.c,v 1.2 2007/03/09 22:25:45 tg Exp $");
  32. #define lodsw(s) __extension__({ \
  33. const uint8_t *lodsw_buf = (const uint8_t *)(s);\
  34. uint16_t lodsw_val; \
  35. \
  36. lodsw_val = lodsw_buf[0]; \
  37. lodsw_val |= lodsw_buf[1] << 8; \
  38. (lodsw_val); \
  39. })
  40. #define lodsd(s) __extension__({ \
  41. const uint8_t *lodsd_buf = (const uint8_t *)(s);\
  42. uint32_t lodsd_val; \
  43. \
  44. lodsd_val = lodsd_buf[0]; \
  45. lodsd_val |= lodsd_buf[1] << 8; \
  46. lodsd_val |= lodsd_buf[2] << 16; \
  47. lodsd_val |= lodsd_buf[3] << 24; \
  48. (lodsd_val); \
  49. })
  50. #define stosw(s,w) do { \
  51. uint8_t *stosw_buf = (uint8_t *)(s); \
  52. uint16_t stosw_val = (w); \
  53. \
  54. stosw_buf[0] = stosw_val & 0xFF; \
  55. stosw_buf[1] = (stosw_val >> 8) & 0xFF; \
  56. } while (0)
  57. #define stosd(s,dw) do { \
  58. uint8_t *stosd_buf = (uint8_t *)(s); \
  59. uint32_t stosd_val = (dw); \
  60. \
  61. stosd_buf[0] = stosd_val & 0xFF; \
  62. stosd_buf[1] = (stosd_val >> 8) & 0xFF; \
  63. stosd_buf[2] = (stosd_val >> 16) & 0xFF; \
  64. stosd_buf[3] = (stosd_val >> 24) & 0xFF; \
  65. } while (0)
  66. void
  67. read_aszdata(int dfd, char **dbuf, size_t *dlen)
  68. {
  69. size_t len;
  70. uint8_t hdrbuf[8];
  71. ADLER_DECL;
  72. if (read(dfd, hdrbuf, 8) != 8)
  73. err(1, "short read");
  74. *dlen = lodsd(hdrbuf + 4);
  75. if ((*dbuf = malloc(*dlen)) == NULL)
  76. err(255, "out of memory trying to allocate %zu bytes", *dlen);
  77. if ((size_t)read(dfd, *dbuf, *dlen) != *dlen)
  78. err(1, "short read");
  79. len = 4;
  80. ADLER_CALC(hdrbuf + 4);
  81. len = *dlen;
  82. ADLER_CALC(*dbuf);
  83. if ((lodsw(hdrbuf) != s1) || (lodsw(hdrbuf + 2) != s2))
  84. err(2, "checksum mismatch, size %zu,"
  85. " want 0x%02X%02X%02X%02X got 0x%04X%04X", *dlen,
  86. hdrbuf[3], hdrbuf[2], hdrbuf[1], hdrbuf[0], s2, s1);
  87. }
  88. void
  89. write_aszdata(int dfd, const char *dbuf, size_t dlen)
  90. {
  91. size_t len;
  92. uint8_t hdrbuf[8];
  93. ADLER_DECL;
  94. stosd(hdrbuf + 4, dlen);
  95. len = 4;
  96. ADLER_CALC(hdrbuf + 4);
  97. len = dlen;
  98. ADLER_CALC(dbuf);
  99. stosw(hdrbuf, s1);
  100. stosw(hdrbuf + 2, s2);
  101. if (write(dfd, hdrbuf, 8) != 8)
  102. err(1, "short write");
  103. if ((size_t)write(dfd, dbuf, dlen) != dlen)
  104. err(1, "short write");
  105. }
  106. int
  107. minilzop(int ifd, int ofd, int compr_alg, int decompress)
  108. {
  109. size_t ilen, olen, n;
  110. char *idata, *odata;
  111. #ifndef SMALL
  112. fprintf(stderr, "minilzop: using algorithm %02X (%s)\n",
  113. compr_alg, compressor_get(compr_alg)->name);
  114. #endif
  115. if (decompress) {
  116. read_aszdata(ifd, &idata, &ilen);
  117. olen = lodsd(idata);
  118. if ((odata = malloc(olen)) == NULL)
  119. err(255, "out of memory trying to allocate %zu bytes",
  120. olen);
  121. if ((n = compressor_get(compr_alg)->decompress(odata, olen,
  122. idata + 4, ilen - 4)) != olen)
  123. errx(1, "size mismatch: decompressed %zu, want %zu",
  124. n, olen);
  125. free(idata);
  126. idata = odata; /* save for later free(3) */
  127. while (olen) {
  128. if ((n = write(ofd, odata, olen)) == (size_t)-1)
  129. err(1, "cannot write");
  130. olen -= n;
  131. odata += n;
  132. }
  133. free(idata);
  134. } else {
  135. size_t cc;
  136. n = 16384;
  137. idata = NULL;
  138. ilen = 0;
  139. slurp_file:
  140. if ((idata = realloc(idata, (n <<= 1))) == NULL)
  141. err(255, "out of memory trying to allocate %zu bytes",
  142. n);
  143. slurp_retry:
  144. if ((cc = read(ifd, idata + ilen, n - ilen)) == (size_t)-1)
  145. err(1, "cannot read");
  146. ilen += cc;
  147. if (cc > 0) {
  148. if (ilen < n)
  149. goto slurp_retry;
  150. goto slurp_file;
  151. }
  152. if ((olen = compressor_get(compr_alg)->compress(&odata, idata,
  153. ilen)) == (size_t)-1)
  154. errx(1, "%s compression failed",
  155. compressor_get(compr_alg)->name);
  156. free(idata);
  157. if ((idata = malloc(olen + 4)) == NULL)
  158. err(255, "out of memory trying to allocate %zu bytes",
  159. olen + 4);
  160. stosd(idata, ilen);
  161. memcpy(idata + 4, odata, olen);
  162. write_aszdata(ofd, idata, olen + 4);
  163. free(idata);
  164. }
  165. return (0);
  166. }