11 #if defined(WITH_BZIP2)
13 #define _RPMBZ_INTERNAL
20 #define BZDONLY(fd) assert(fdGetIo(fd) == bzdio)
22 const char * rpmbzStrerror(rpmbz bz)
25 return BZ2_bzerror(bz->bzfile, &bz->bzerr);
29 void rpmbzClose(rpmbz bz,
int abort,
const char ** errmsg)
32 if (bz->bzfile != NULL) {
33 if (bz->omode == O_RDONLY)
34 BZ2_bzReadClose(&bz->bzerr, bz->bzfile);
36 BZ2_bzWriteClose(&bz->bzerr, bz->bzfile, abort,
37 &bz->nbytes_in, &bz->nbytes_out);
39 if (bz->bzerr != BZ_OK && errmsg)
40 *errmsg = rpmbzStrerror(bz);
48 rpmbz rpmbzFree( rpmbz bz,
int abort)
52 rpmbzClose(bz, abort, NULL);
54 (void) fclose(bz->fp);
62 rpmbz rpmbzNew(
const char * path,
const char * fmode,
int fdno)
68 mode_t omode = O_RDONLY;
71 const char * s = fmode;
74 char *te = t +
sizeof(stdio) - 2;
77 assert(fmode != NULL);
91 while ((c = *s++) != 0) {
100 if (t < te) *t++ = c;
103 if (small < 0) small = 0;
110 if (verbosity < 0) verbosity = 0;
111 if (verbosity < 4) verbosity++;
114 if (c >= (
int)
'0' && c <= (int)
'9')
115 level = c - (int)
'0';
120 bz = rpmbzInit(level, small, verbosity, omode);
123 if ((bz->fp = fdopen(fdno, stdio)) != NULL)
124 bz->bzfile = (bz->omode == O_RDONLY)
125 ? BZ2_bzReadOpen(&bz->bzerr, bz->fp, bz->V, bz->S, NULL, 0)
126 : BZ2_bzWriteOpen(&bz->bzerr, bz->fp, bz->B, bz->V, bz->W);
127 }
else if (path != NULL) {
128 if ((bz->fp = fopen(path, stdio)) != NULL)
129 bz->bzfile = (bz->omode == O_RDONLY)
130 ? BZ2_bzReadOpen(&bz->bzerr, bz->fp, bz->V, bz->S, NULL, 0)
131 : BZ2_bzWriteOpen(&bz->bzerr, bz->fp, bz->B, bz->V, bz->W);
135 return (bz->bzfile != NULL ? bz : rpmbzFree(bz, 0));
142 static void rpmbzCompress(rpmbz bz, rpmzJob job)
146 bz_stream *bzstrm = &bz->strm;
151 bzstrm->bzfree = NULL;
152 bzstrm->bzalloc = NULL;
153 bzstrm->opaque = NULL;
154 if ((ret = BZ2_bzCompressInit(bzstrm, bz->B, bz->V, bz->W)) != BZ_OK)
155 bail(
"not enough memory",
"BZ2_bzCompressInit");
157 bzstrm->next_in = job->in->buf;
158 bzstrm->next_out = job->out->buf;
159 bzstrm->avail_out = job->out->len;
165 while (len > _PIGZMAX) {
166 bzstrm->avail_in = _PIGZMAX;
167 if ((ret = BZ2_bzCompress(bzstrm, BZ_RUN)) != BZ_RUN_OK)
168 fprintf(stderr,
"*** BZ2_bzCompress(%d): %d\n", BZ_RUN, ret);
169 assert(bzstrm->avail_in == 0 && bzstrm->avail_out != 0);
175 bzstrm->avail_in = (unsigned)len;
176 ret = BZ2_bzCompress(bzstrm, BZ_FINISH);
177 if (!(ret == BZ_FINISH_OK || ret == BZ_STREAM_END))
178 fprintf(stderr,
"*** BZ2_bzCompress(%d): %d\n", BZ_FINISH, ret);
179 if ((ret = BZ2_bzCompressEnd(bzstrm)) != BZ_OK)
180 fprintf(stderr,
"*** BZ2_bzCompressEnd: %d\n", ret);
182 assert(bzstrm->avail_in == 0 && bzstrm->avail_out != 0);
189 static void rpmbzDecompress(rpmbz bz, rpmzJob job)
193 bz_stream *bzstrm = &bz->strm;
197 bzstrm->bzfree = NULL;
198 bzstrm->bzalloc = NULL;
199 bzstrm->opaque = NULL;
200 if ((ret = BZ2_bzDecompressInit(bzstrm, bz->V, bz->S)) != BZ_OK)
201 bail(
"not enough memory",
"BZ2_bzDecompressInit");
203 bzstrm->next_in = job->in->buf;
204 bzstrm->avail_in = job->in->len;
205 bzstrm->next_out = job->out->buf;
206 bzstrm->avail_out = job->out->len;
208 if ((ret = BZ2_bzDecompress(bzstrm)) != BZ_RUN_OK)
209 fprintf(stderr,
"*** BZ2_bzDecompress: %d\n", ret);
211 job->out->len -= bzstrm->avail_out;
213 if ((ret = BZ2_bzDecompressEnd(bzstrm)) != BZ_OK)
214 fprintf(stderr,
"*** BZ2_bzDecompressEnd: %d\n", ret);
221 ssize_t rpmbzRead(rpmbz bz,
char * buf,
size_t count,
222 const char ** errmsg)
229 assert(bz->bzfile != NULL);
231 if (bz->bzfile == NULL)
return 0;
233 rc = BZ2_bzRead(&bz->bzerr, bz->bzfile, buf, (
int)count);
235 case BZ_STREAM_END: {
236 void * unused = NULL;
239 BZ2_bzReadGetUnused(&bz->bzerr, bz->bzfile, &unused, &nUnused);
240 if (unused != NULL && nUnused > 0)
241 unused = memcpy(
xmalloc(nUnused), unused, nUnused);
246 rpmbzClose(bz, 0, NULL);
247 bz->bzfile = BZ2_bzReadOpen(&bz->bzerr, bz->fp, bz->V, bz->S,
249 unused =
_free(unused);
257 *errmsg = rpmbzStrerror(bz);
258 rpmbzClose(bz, 1, NULL);
265 ssize_t rpmbzWrite(rpmbz bz,
const char * buf,
size_t count,
266 const char ** errmsg)
272 assert(bz->bzfile != NULL);
273 BZ2_bzWrite(&bz->bzerr, bz->bzfile, (
void *)buf, (
int)count);
280 *errmsg = rpmbzStrerror(bz);
281 rpmbzClose(bz, 1, NULL);
295 static rpmbz rpmbzOpen(
const char * path,
const char * fmode)
299 return rpmbzNew(path, fmode, -1);
302 static rpmbz rpmbzFdopen(
void * _fdno,
const char * fmode)
306 int fdno = (int)((
long)_fdno);
307 return rpmbzNew(NULL, fmode, fdno);
310 static int rpmbzFlush(
void * _bz)
313 rpmbz bz = (rpmbz) _bz;
314 return BZ2_bzflush(bz->bzfile);
318 static inline void * bzdFileno(
FD_t fd)
325 for (i = fd->
nfps; i >= 0; i--) {
327 if (fps->
io != bzdio)
337 static FD_t bzdOpen(
const char * path,
const char * fmode)
342 rpmbz bz = rpmbzOpen(path, fmode);
346 fd =
fdNew(
"open (bzdOpen)");
353 return fdLink(fd,
"bzdOpen");
358 static FD_t bzdFdopen(
void * cookie,
const char * fmode)
364 rpmbz bz = rpmbzFdopen((
void *)((
long)fdno), fmode);
372 fdPush(fd, bzdio, bz, fdno);
374 return fdLink(fd,
"bzdFdopen");
379 static int bzdFlush(
void * cookie)
384 rpmbz bz = (rpmbz) bzdFileno(fd);
385 return rpmbzFlush(bz);
391 static ssize_t bzdRead(
void * cookie,
char * buf,
size_t count)
396 rpmbz bz = (rpmbz) bzdFileno(fd);
403 rc = rpmbzRead(bz, buf, count, (
const char **)&fd->
errcookie);
415 static ssize_t bzdWrite(
void * cookie,
const char * buf,
size_t count)
420 rpmbz bz = (rpmbz) bzdFileno(fd);
430 rc = rpmbzWrite(bz, buf, count, (
const char **)&fd->
errcookie);
438 static int bzdSeek(
void * cookie,
_libio_pos_t pos,
int whence)
442 rpmbz bz = (rpmbz) bzdFileno(fd);
446 return rpmbzSeek(bz, pos, whence);
449 static int bzdClose(
void * cookie)
454 rpmbz bz = (rpmbz) bzdFileno(fd);
459 if (bz->bzfile == NULL)
465 rpmbzClose(bz, 0, (
const char **)&fd->
errcookie);
475 DBGIO(fd, (stderr,
"==>\tbzdClose(%p) rc %lx %s\n", cookie, (
unsigned long)rc,
fdbg(fd)));
481 bz = rpmbzFree(bz, 0);
483 fd =
fdFree(fd,
"open (bzdClose)");
489 static struct FDIO_s bzdio_s = {
490 bzdRead, bzdWrite, bzdSeek, bzdClose, bzdOpen, bzdFdopen, bzdFlush,