17 # define UINT32_C(n) n ## U 20 # define UINT32_MAX UINT32_C(4294967295) 22 #if SIZEOF_UNSIGNED_LONG == 4 24 # define UINT64_C(n) n ## ULL 28 # define UINT64_C(n) n ## UL 32 # define UINT64_MAX UINT64_C(18446744073709551615) 37 #ifndef LZMA_PRESET_DEFAULT 38 #define LZMA_PRESET_DEFAULT UINT32_C(6) 45 #define XZDONLY(fd) assert(fdGetIo(fd) == xzdio) 47 #define kBufferSize (1 << 15) 49 typedef struct xzfile {
61 static XZFILE *xzopen_internal(
const char *path,
const char *mode,
int fdno,
int xz)
65 int level = LZMA_PRESET_DEFAULT;
72 for (; *mode !=
'\0'; mode++) {
75 else if (*mode ==
'r')
77 else if (*mode >=
'0' && *mode <=
'9')
78 level = (int)(*mode -
'0');
81 fp = fdopen(fdno, encoding ?
"w" :
"r");
83 fp = fopen(path, encoding ?
"w" :
"r");
86 xzfile = (XZFILE *) calloc(1,
sizeof(*xzfile));
92 xzfile->encoding = encoding;
94 tmp = (lzma_stream)LZMA_STREAM_INIT;
98 ret = lzma_easy_encoder(&xzfile->strm, level, LZMA_CHECK_CRC32);
100 lzma_options_lzma options;
101 (void) lzma_lzma_preset(&options, level);
102 ret = lzma_alone_encoder(&xzfile->strm, &options);
108 ret = lzma_auto_decoder(&xzfile->strm, 100<<20, 0);
110 if (ret != LZMA_OK) {
112 memset(xzfile, 0,
sizeof(*xzfile));
121 static XZFILE *lzopen(
const char *path,
const char *mode)
125 return xzopen_internal(path, mode, -1, 0);
129 static XZFILE *lzdopen(
int fdno,
const char *mode)
135 return xzopen_internal(0, mode, fdno, 0);
139 static XZFILE *xzopen(
const char *path,
const char *mode)
143 return xzopen_internal(path, mode, -1, 1);
147 static XZFILE *xzdopen(
int fdno,
const char *mode)
153 return xzopen_internal(0, mode, fdno, 1);
156 static int xzflush(XZFILE *xzfile)
160 return fflush(xzfile->fp);
163 static int xzclose( XZFILE *xzfile)
173 if (xzfile->encoding) {
175 xzfile->strm.avail_out = kBufferSize;
176 xzfile->strm.next_out = (uint8_t *)xzfile->buf;
177 ret = lzma_code(&xzfile->strm, LZMA_FINISH);
178 if (ret != LZMA_OK && ret != LZMA_STREAM_END)
180 n = kBufferSize - xzfile->strm.avail_out;
181 if (n && fwrite(xzfile->buf, 1, n, xzfile->fp) != n)
183 if (ret == LZMA_STREAM_END)
187 lzma_end(&xzfile->strm);
188 rc = fclose(xzfile->fp);
189 memset(xzfile, 0,
sizeof(*xzfile));
195 static ssize_t xzread(XZFILE *xzfile,
void *buf,
size_t len)
202 if (!xzfile || xzfile->encoding)
207 xzfile->strm.next_out = (uint8_t *) buf;
209 xzfile->strm.avail_out = len;
211 if (!xzfile->strm.avail_in) {
212 xzfile->strm.next_in = (uint8_t *)xzfile->buf;
213 xzfile->strm.avail_in = fread(xzfile->buf, 1, kBufferSize, xzfile->fp);
214 if (!xzfile->strm.avail_in)
217 ret = lzma_code(&xzfile->strm, LZMA_RUN);
218 if (ret == LZMA_STREAM_END) {
220 return len - xzfile->strm.avail_out;
224 if (!xzfile->strm.avail_out)
233 static ssize_t xzwrite(XZFILE *xzfile,
void *buf,
size_t len)
240 if (!xzfile || !xzfile->encoding)
245 xzfile->strm.next_in = (
const uint8_t *) buf;
247 xzfile->strm.avail_in = len;
249 xzfile->strm.next_out = (uint8_t *)xzfile->buf;
250 xzfile->strm.avail_out = kBufferSize;
251 ret = lzma_code(&xzfile->strm, LZMA_RUN);
254 n = kBufferSize - xzfile->strm.avail_out;
255 if (n && fwrite(xzfile->buf, 1, n, xzfile->fp) != n)
257 if (!xzfile->strm.avail_in)
265 static inline void * xzdFileno(
FD_t fd)
272 for (i = fd->
nfps; i >= 0; i--) {
286 static FD_t lzdOpen(
const char * path,
const char * fmode)
291 mode_t mode = (fmode && fmode[0] ==
'w' ? O_WRONLY : O_RDONLY);
292 XZFILE * xzfile = lzopen(path, fmode);
296 fd =
fdNew(
"open (lzdOpen)");
298 fdSetOpen(fd, path, fileno(xzfile->fp), mode);
299 return fdLink(fd,
"lzdOpen");
304 static FD_t lzdFdopen(
void * cookie,
const char * fmode)
312 assert(fmode != NULL);
314 if (fdno < 0)
return NULL;
315 xzfile = lzdopen(fdno, fmode);
316 if (xzfile == NULL)
return NULL;
318 return fdLink(fd,
"lzdFdopen");
323 static FD_t xzdOpen(
const char * path,
const char * fmode)
328 mode_t mode = (fmode && fmode[0] ==
'w' ? O_WRONLY : O_RDONLY);
329 XZFILE * xzfile = xzopen(path, fmode);
333 fd =
fdNew(
"open (xzdOpen)");
335 fdSetOpen(fd, path, fileno(xzfile->fp), mode);
336 return fdLink(fd,
"xzdOpen");
341 static FD_t xzdFdopen(
void * cookie,
const char * fmode)
349 assert(fmode != NULL);
351 if (fdno < 0)
return NULL;
352 xzfile = xzdopen(fdno, fmode);
353 if (xzfile == NULL)
return NULL;
355 return fdLink(fd,
"xzdFdopen");
360 static int xzdFlush(
void * cookie)
365 XZFILE * xzfile = (XZFILE *) xzdFileno(fd);
366 return xzflush(xzfile);
373 static ssize_t xzdRead(
void * cookie,
char * buf,
size_t count)
383 xzfile = (XZFILE *) xzdFileno(fd);
384 assert(xzfile != NULL);
387 rc = xzread(xzfile, buf, count);
389 DBGIO(fd, (stderr,
"==>\txzdRead(%p,%p,%u) rc %lx %s\n", cookie, buf, (
unsigned)count, (
unsigned long)rc,
fdbg(fd)));
392 }
else if (rc >= 0) {
404 static ssize_t xzdWrite(
void * cookie,
const char * buf,
size_t count)
416 xzfile = (XZFILE *) xzdFileno(fd);
419 rc = xzwrite(xzfile, (
void *)buf, count);
420 DBGIO(fd, (stderr,
"==>\txzdWrite(%p,%p,%u) rc %lx %s\n", cookie, buf, (
unsigned)count, (
unsigned long)rc,
fdbg(fd)));
439 static int xzdClose(
void * cookie)
445 const char * errcookie;
448 xzfile = (XZFILE *) xzdFileno(fd);
450 if (xzfile == NULL)
return -2;
451 errcookie = strerror(ferror(xzfile->fp));
455 rc = xzclose(xzfile);
462 DBGIO(fd, (stderr,
"==>\txzdClose(%p) rc %lx %s\n", cookie, (
unsigned long)rc,
fdbg(fd)));
467 fd =
fdFree(fd,
"open (xzdClose)");
473 static struct FDIO_s lzdio_s = {
474 xzdRead, xzdWrite, xzdSeek, xzdClose, lzdOpen, lzdFdopen, xzdFlush,
481 static struct FDIO_s xzdio_s = {
482 xzdRead, xzdWrite, xzdSeek, xzdClose, xzdOpen, xzdFdopen, xzdFlush,
static void fdstat_enter(FD_t fd, int opx)
static void fdSetFdno(FD_t fd, int fdno)
const char * fdbg(FD_t fd)
FD_t fdLink(void *cookie, const char *msg)
static void fdPush(FD_t fd, FDIO_t io, void *fp, int fdno)
FD_t fdNew(const char *msg)
static void fdUpdateDigests(FD_t fd, const unsigned char *buf, ssize_t buflen)
Update digest(s) attached to fd.
FD_t fdFree(FD_t fd, const char *msg)
static void fdstat_print(FD_t fd, const char *msg, FILE *fp)
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
static void fdPop(FD_t fd)
static void fdSetOpen(FD_t fd, const char *path, int flags, mode_t mode)
The FD_t File Handle data structure.
static int fdFileno(void *cookie)
static FD_t c2f(void *cookie)
static void fdstat_exit(FD_t fd, int opx, ssize_t rc)