compression.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #include <config.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <errno.h>
  6. #ifdef WITH_ZLIB
  7. #include <zlib.h>
  8. #endif
  9. #ifdef WITH_BZ2
  10. #include <bzlib.h>
  11. #endif
  12. #include <dpkg.h>
  13. #include "dpkg.h"
  14. #include "dpkg-db.h"
  15. static void
  16. fd_fd_filter(int fd_in, int fd_out,
  17. const char *file, const char *cmd, const char *args,
  18. const char *desc)
  19. {
  20. if (fd_in != 0) {
  21. m_dup2(fd_in, 0);
  22. close(fd_in);
  23. }
  24. if (fd_out != 1) {
  25. m_dup2(fd_out, 1);
  26. close(fd_out);
  27. }
  28. execlp(file, cmd, args, NULL);
  29. ohshite(_("%s: failed to exec '%s %s'"), desc, cmd, args);
  30. }
  31. void decompress_cat(enum compress_type type, int fd_in, int fd_out, char *desc, ...) {
  32. va_list al;
  33. struct varbuf v = VARBUF_INIT;
  34. va_start(al,desc);
  35. varbufvprintf(&v, desc, al);
  36. va_end(al);
  37. switch(type) {
  38. case compress_type_gzip:
  39. #ifdef WITH_ZLIB
  40. {
  41. char buffer[4096];
  42. int actualread;
  43. gzFile gzfile = gzdopen(fd_in, "r");
  44. while ((actualread= gzread(gzfile,buffer,sizeof(buffer))) > 0) {
  45. if (actualread < 0 ) {
  46. int err = 0;
  47. const char *errmsg = gzerror(gzfile, &err);
  48. if (err == Z_ERRNO) {
  49. if (errno == EINTR) continue;
  50. errmsg= strerror(errno);
  51. }
  52. ohshite(_("%s: internal gzip error: `%s'"), v.buf, errmsg);
  53. }
  54. write(fd_out,buffer,actualread);
  55. }
  56. }
  57. exit(0);
  58. #else
  59. fd_fd_filter(fd_in, fd_out, GZIP, "gzip", "-dc", v.buf);
  60. #endif
  61. case compress_type_bzip2:
  62. #ifdef WITH_BZ2
  63. {
  64. char buffer[4096];
  65. int actualread;
  66. BZFILE *bzfile = BZ2_bzdopen(fd_in, "r");
  67. while ((actualread= BZ2_bzread(bzfile,buffer,sizeof(buffer))) > 0) {
  68. if (actualread < 0 ) {
  69. int err = 0;
  70. const char *errmsg = BZ2_bzerror(bzfile, &err);
  71. if (err == BZ_IO_ERROR) {
  72. if (errno == EINTR) continue;
  73. errmsg= strerror(errno);
  74. }
  75. ohshite(_("%s: internal bzip2 error: `%s'"), v.buf, errmsg);
  76. }
  77. write(fd_out,buffer,actualread);
  78. }
  79. }
  80. exit(0);
  81. #else
  82. fd_fd_filter(fd_in, fd_out, BZIP2, "bzip2", "-dc", v.buf);
  83. #endif
  84. case compress_type_lzma:
  85. fd_fd_filter(fd_in, fd_out, LZMA, "lzma", "-dc", v.buf);
  86. case compress_type_cat:
  87. fd_fd_copy(fd_in, fd_out, -1, _("%s: decompression"), v.buf);
  88. exit(0);
  89. default:
  90. exit(1);
  91. }
  92. }
  93. void compress_cat(enum compress_type type, int fd_in, int fd_out, const char *compression, char *desc, ...) {
  94. va_list al;
  95. struct varbuf v = VARBUF_INIT;
  96. char combuf[6];
  97. va_start(al,desc);
  98. varbufvprintf(&v, desc, al);
  99. va_end(al);
  100. if(compression == NULL) compression= "9";
  101. else if (*compression == '0')
  102. type = compress_type_cat;
  103. switch(type) {
  104. case compress_type_gzip:
  105. #ifdef WITH_ZLIB
  106. {
  107. int actualread, actualwrite;
  108. char buffer[4096];
  109. gzFile gzfile;
  110. strncpy(combuf, "w9", sizeof(combuf));
  111. combuf[1]= *compression;
  112. gzfile = gzdopen(1, combuf);
  113. while((actualread = read(0,buffer,sizeof(buffer))) > 0) {
  114. if (actualread < 0 ) {
  115. if (errno == EINTR) continue;
  116. ohshite(_("%s: internal gzip error: read: `%s'"), v.buf, strerror(errno));
  117. }
  118. actualwrite= gzwrite(gzfile,buffer,actualread);
  119. if (actualwrite < 0 ) {
  120. int err = 0;
  121. const char *errmsg = gzerror(gzfile, &err);
  122. if (err == Z_ERRNO) {
  123. if (errno == EINTR) continue;
  124. errmsg= strerror(errno);
  125. }
  126. ohshite(_("%s: internal gzip error: write: `%s'"), v.buf, errmsg);
  127. }
  128. if (actualwrite != actualread)
  129. ohshite(_("%s: internal gzip error: read(%i) != write(%i)"), v.buf, actualread, actualwrite);
  130. }
  131. gzclose(gzfile);
  132. exit(0);
  133. }
  134. #else
  135. strncpy(combuf, "-9c", sizeof(combuf));
  136. combuf[1]= *compression;
  137. fd_fd_filter(fd_in, fd_out, GZIP, "gzip", combuf, v.buf);
  138. #endif
  139. case compress_type_bzip2:
  140. #ifdef WITH_BZ2
  141. {
  142. int actualread, actualwrite;
  143. char buffer[4096];
  144. BZFILE *bzfile;
  145. strncpy(combuf, "w9", sizeof(combuf));
  146. combuf[1]= *compression;
  147. bzfile = BZ2_bzdopen(1, combuf);
  148. while((actualread = read(0,buffer,sizeof(buffer))) > 0) {
  149. if (actualread < 0 ) {
  150. if (errno == EINTR) continue;
  151. ohshite(_("%s: internal bzip2 error: read: `%s'"), v.buf, strerror(errno));
  152. }
  153. actualwrite= BZ2_bzwrite(bzfile,buffer,actualread);
  154. if (actualwrite < 0 ) {
  155. int err = 0;
  156. const char *errmsg = BZ2_bzerror(bzfile, &err);
  157. if (err == BZ_IO_ERROR) {
  158. if (errno == EINTR) continue;
  159. errmsg= strerror(errno);
  160. }
  161. ohshite(_("%s: internal bzip2 error: write: `%s'"), v.buf, errmsg);
  162. }
  163. if (actualwrite != actualread)
  164. ohshite(_("%s: internal bzip2 error: read(%i) != write(%i)"), v.buf, actualread, actualwrite);
  165. }
  166. BZ2_bzclose(bzfile);
  167. exit(0);
  168. }
  169. #else
  170. strncpy(combuf, "-9c", sizeof(combuf));
  171. combuf[1]= *compression;
  172. fd_fd_filter(fd_in, fd_out, BZIP2, "bzip2", combuf, v.buf);
  173. #endif
  174. case compress_type_lzma:
  175. strncpy(combuf, "-9c", sizeof(combuf));
  176. combuf[1] = *compression;
  177. fd_fd_filter(fd_in, fd_out, LZMA, "lzma", combuf, v.buf);
  178. case compress_type_cat:
  179. fd_fd_copy(fd_in, fd_out, -1, _("%s: compression"), v.buf);
  180. exit(0);
  181. default:
  182. exit(1);
  183. }
  184. }