expand.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * cpio - copy file archives in and out
  3. *
  4. * Gunnar Ritter, Freiburg i. Br., Germany, April 2003.
  5. */
  6. /*
  7. * Copyright (c) 2003 Gunnar Ritter
  8. *
  9. * This software is provided 'as-is', without any express or implied
  10. * warranty. In no event will the authors be held liable for any damages
  11. * arising from the use of this software.
  12. *
  13. * Permission is granted to anyone to use this software for any purpose,
  14. * including commercial applications, and to alter it and redistribute
  15. * it freely, subject to the following restrictions:
  16. *
  17. * 1. The origin of this software must not be misrepresented; you must not
  18. * claim that you wrote the original software. If you use this software
  19. * in a product, an acknowledgment in the product documentation would be
  20. * appreciated but is not required.
  21. *
  22. * 2. Altered source versions must be plainly marked as such, and must not be
  23. * misrepresented as being the original software.
  24. *
  25. * 3. This notice may not be removed or altered from any source distribution.
  26. */
  27. /* Sccsid @(#)expand.c 1.6 (gritter) 12/15/03 */
  28. #include <sys/types.h>
  29. #include <sys/stat.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <unistd.h>
  33. #include "cpio.h"
  34. #define DLE 144
  35. static void
  36. zexread(char *data, size_t size, int doswap)
  37. {
  38. if (bread(data, size) != size)
  39. unexeoa();
  40. if (doswap)
  41. swap(data, size, bflag || sflag, bflag || Sflag);
  42. }
  43. #define nextbyte() ( \
  44. ipos >= sizeof ibuf && isize > 0 ? ( \
  45. zexread(ibuf, isize>sizeof ibuf?sizeof ibuf:isize, doswap), \
  46. ipos = 0 \
  47. ) : 0, \
  48. isize--, \
  49. ibuf[ipos++] & 0377 \
  50. )
  51. #define nextbit() ( \
  52. ibit = ibit >= 7 ? (ibyte = nextbyte(), 0) : ibit + 1, \
  53. isize < 0 ? (ieof = 1, -1) : (ibyte & (1<<ibit)) >> ibit \
  54. )
  55. #define sixbits(n) { \
  56. int t; \
  57. (n) = 0; \
  58. for (t = 0; t < 6; t++) \
  59. (n) |= nextbit() << t; \
  60. }
  61. #define eightbits(n) { \
  62. int t; \
  63. (n) = 0; \
  64. for (t = 0; t < 8; t++) \
  65. (n) |= nextbit() << t; \
  66. }
  67. static void
  68. zexwrite(int *tfd, char *data, size_t size, uint32_t *crc, int *val,
  69. const char *tgt, long long *nsize)
  70. {
  71. if (size) {
  72. if (size > *nsize)
  73. size = *nsize;
  74. if (*tfd >= 0 && write(*tfd, data, size) != size) {
  75. emsg(3, "Cannot write \"%s\"", tgt);
  76. *tfd = -1;
  77. *val = -1;
  78. }
  79. *crc = zipcrc(*crc, (unsigned char *)data, size);
  80. *nsize -= size;
  81. }
  82. }
  83. #define wadd(c) ( \
  84. wpos >= sizeof wbuf ? ( \
  85. zexwrite(&tfd, wbuf, sizeof wbuf, crc, &val, tgt, &nsize), \
  86. wpos = 0 \
  87. ) : 0, \
  88. wsize++, \
  89. wbuf[wpos++] = (c) \
  90. )
  91. #define zex_L(x) ( \
  92. f->f_cmethod == C_REDUCED1 ? (x) & 0177 : \
  93. f->f_cmethod == C_REDUCED2 ? (x) & 077 : \
  94. f->f_cmethod == C_REDUCED3 ? (x) & 037 : \
  95. /* f->f_cmethod == C_REDUCED4 */ (x) & 017 \
  96. )
  97. #define zex_F(x) ( \
  98. f->f_cmethod == C_REDUCED1 ? (x) == 0177 ? 2 : 3 : \
  99. f->f_cmethod == C_REDUCED2 ? (x) == 077 ? 2 : 3 : \
  100. f->f_cmethod == C_REDUCED3 ? (x) == 037 ? 2 : 3 : \
  101. /* f->f_cmethod == C_REDUCED4 */ (x) == 017 ? 2 : 3 \
  102. )
  103. #define zex_D(x, y) ( \
  104. f->f_cmethod == C_REDUCED1 ? (((x)&0200)>>7) * 0400 + (y) + 1 : \
  105. f->f_cmethod == C_REDUCED2 ? (((x)&0300)>>6) * 0400 + (y) + 1 : \
  106. f->f_cmethod == C_REDUCED3 ? (((x)&0340)>>5) * 0400 + (y) + 1 : \
  107. /* f->f_cmethod == C_REDUCED4 */ (((x)&0360)>>4) * 0400 + (y) + 1 \
  108. )
  109. int
  110. zipexpand(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc)
  111. {
  112. char fset[256][33];
  113. char ibuf[4096], ibyte = 0, wbuf[8192];
  114. long ipos = sizeof ibuf, wpos = 0, isize = f->f_csize, wsize = 0;
  115. int val = 0, ieof = 0;
  116. int c = 0, i, j, k, n, ibit = 7, lastc, state, v = 0, len = 0;
  117. long long nsize = f->f_st.st_size;
  118. *crc = 0;
  119. memset(fset, 0, sizeof fset);
  120. for (j = 255; j >= 0; j--) {
  121. sixbits(n);
  122. for (i = 0; i < n; i++) {
  123. eightbits(fset[j][i]);
  124. }
  125. fset[j][32] = n<1?0:n<3?1:n<5?2:n<9?3:n<17?4:n<37?5:n<65?6:7;
  126. }
  127. lastc = 0;
  128. state = 0;
  129. while (ieof == 0) {
  130. if (fset[lastc][32] == 0) {
  131. eightbits(c);
  132. } else {
  133. if (nextbit() != 0) {
  134. eightbits(c);
  135. } else {
  136. i = 0;
  137. for (k = 0; k < fset[lastc][32]; k++)
  138. i |= nextbit() << k;
  139. c = fset[lastc][i] & 0377;
  140. }
  141. }
  142. lastc = c;
  143. switch (state) {
  144. case 0:
  145. if (c != DLE)
  146. wadd(c);
  147. else
  148. state = 1;
  149. break;
  150. case 1:
  151. if (c != 0) {
  152. v = c;
  153. len = zex_L(v);
  154. state = zex_F(len);
  155. } else {
  156. wadd(DLE);
  157. state = 0;
  158. }
  159. break;
  160. case 2:
  161. len += c;
  162. state = 3;
  163. break;
  164. case 3:
  165. n = wsize - zex_D(v, c);
  166. for (i = 0; i < len + 3; i++) {
  167. c = n+i >= 0 ? wbuf[n+i&sizeof wbuf-1]&0377 : 0;
  168. wadd(c);
  169. }
  170. state = 0;
  171. }
  172. }
  173. zexwrite(&tfd, wbuf, wpos, crc, &val, tgt, &nsize);
  174. while (isize >= 0)
  175. nextbyte();
  176. return val;
  177. }