8 #if HAVE_LIBIO_H && defined(_G_IO_IO_FILE_VERSION)
12 #include <rpm/rpmlog.h>
13 #include <rpm/rpmmacro.h>
14 #include <rpm/rpmfileutil.h>
15 #include <rpm/rpmsw.h>
16 #include <rpm/rpmurl.h>
18 #include "rpmio/rpmio_internal.h"
22 typedef struct _FDSTACK_s {
29 * Cumulative statistics for a descriptor.
32 struct rpmop_s ops[FDSTAT_MAX]; /*!< Cumulative statistics. */
36 * The FD_t File Handle data structure.
41 #define RPMIO_DEBUG_IO 0x40000000
42 #define RPMIO_DEBUG_REFS 0x20000000
44 #define FDMAGIC 0x04463138
47 int urlType; /* ufdio: */
49 ssize_t bytesRemain; /* ufdio: */
51 int syserrno; /* last system errno encountered */
52 const void *errcookie; /* gzdio/bzdio/ufdio/xzdio: */
54 FDSTAT_t stats; /* I/O statistics */
56 rpmDigestBundle digests;
59 #define FDSANE(fd) assert(fd && fd->magic == FDMAGIC)
61 #define DBG(_f, _m, _x) \
63 if ((_rpmio_debug | ((_f) ? ((FD_t)(_f))->flags : 0)) & (_m)) fprintf _x \
65 #define DBGIO(_f, _x) DBG((_f), RPMIO_DEBUG_IO, _x)
66 #define DBGREFS(_f, _x) DBG((_f), RPMIO_DEBUG_REFS, _x)
68 static FDIO_t fdGetIo(FD_t fd)
71 return fd->fps[fd->nfps].io;
74 static void fdSetIo(FD_t fd, FDIO_t io)
77 fd->fps[fd->nfps].io = io;
80 static void * fdGetFp(FD_t fd)
83 return fd->fps[fd->nfps].fp;
86 static void fdSetFp(FD_t fd, void * fp)
89 fd->fps[fd->nfps].fp = fp;
92 static void fdSetFdno(FD_t fd, int fdno)
95 fd->fps[fd->nfps].fdno = fdno;
98 static void fdPush(FD_t fd, FDIO_t io, void * fp, int fdno)
101 if (fd->nfps >= (sizeof(fd->fps)/sizeof(fd->fps[0]) - 1))
109 static void fdPop(FD_t fd)
112 if (fd->nfps < 0) return;
119 static FD_t c2f(void * cookie)
121 FD_t fd = (FD_t) cookie;
126 void fdSetBundle(FD_t fd, rpmDigestBundle bundle)
129 fd->digests = bundle;
132 rpmDigestBundle fdGetBundle(FD_t fd)
138 #define FDNREFS(fd) (fd ? ((FD_t)fd)->nrefs : -9)
140 #define FDONLY(fd) assert(fdGetIo(fd) == fdio)
141 #define GZDONLY(fd) assert(fdGetIo(fd) == gzdio)
142 #define BZDONLY(fd) assert(fdGetIo(fd) == bzdio)
143 #define LZDONLY(fd) assert(fdGetIo(fd) == xzdio || fdGetIo(fd) == lzdio)
145 #define UFDONLY(fd) /* assert(fdGetIo(fd) == ufdio) */
150 static int noLibio = 0;
152 static int noLibio = 1;
156 * \name RPMIO Vectors.
158 typedef ssize_t (*fdio_read_function_t) (void *cookie, char *buf, size_t nbytes);
159 typedef ssize_t (*fdio_write_function_t) (void *cookie, const char *buf, size_t nbytes);
160 typedef int (*fdio_seek_function_t) (void *cookie, _libio_pos_t pos, int whence);
161 typedef int (*fdio_close_function_t) (void *cookie);
162 typedef FD_t (*fdio_ref_function_t) ( void * cookie, const char * msg);
163 typedef FD_t (*fdio_deref_function_t) ( FD_t fd, const char * msg);
164 typedef FD_t (*fdio_new_function_t) (const char * msg);
165 typedef int (*fdio_fileno_function_t) (void * cookie);
166 typedef FD_t (*fdio_open_function_t) (const char * path, int flags, mode_t mode);
167 typedef FD_t (*fdio_fopen_function_t) (const char * path, const char * fmode);
168 typedef void * (*fdio_ffileno_function_t) (FD_t fd);
169 typedef int (*fdio_fflush_function_t) (FD_t fd);
174 fdio_read_function_t read;
175 fdio_write_function_t write;
176 fdio_seek_function_t seek;
177 fdio_close_function_t close;
179 fdio_ref_function_t _fdref;
180 fdio_deref_function_t _fdderef;
181 fdio_new_function_t _fdnew;
182 fdio_fileno_function_t _fileno;
184 fdio_open_function_t _open;
185 fdio_fopen_function_t _fopen;
186 fdio_ffileno_function_t _ffileno;
187 fdio_fflush_function_t _fflush;
191 static const FDIO_t fdio;
192 static const FDIO_t fpio;
193 static const FDIO_t ufdio;
194 static const FDIO_t gzdio;
195 static const FDIO_t bzdio;
196 static const FDIO_t xzdio;
197 static const FDIO_t lzdio;
200 * Update digest(s) attached to fd.
202 static void fdUpdateDigests(FD_t fd, const unsigned char * buf, size_t buflen);
206 int _rpmio_debug = 0;
208 /* =============================================================== */
210 static const char * fdbg(FD_t fd)
212 static char buf[BUFSIZ];
220 if (fd->bytesRemain != -1) {
221 sprintf(be, " clen %d", (int)fd->bytesRemain);
225 for (i = fd->nfps; i >= 0; i--) {
226 FDSTACK_t * fps = &fd->fps[i];
231 if (fps->io == fdio) {
232 sprintf(be, "FD %d fp %p", fps->fdno, fps->fp);
233 } else if (fps->io == ufdio) {
234 sprintf(be, "UFD %d fp %p", fps->fdno, fps->fp);
236 } else if (fps->io == gzdio) {
237 sprintf(be, "GZD %p fdno %d", fps->fp, fps->fdno);
240 } else if (fps->io == bzdio) {
241 sprintf(be, "BZD %p fdno %d", fps->fp, fps->fdno);
244 } else if (fps->io == xzdio) {
245 sprintf(be, "XZD %p fdno %d", fps->fp, fps->fdno);
246 } else if (fps->io == lzdio) {
247 sprintf(be, "LZD %p fdno %d", fps->fp, fps->fdno);
249 } else if (fps->io == fpio) {
250 sprintf(be, "%s %p(%d) fdno %d",
251 (fps->fdno < 0 ? "LIBIO" : "FP"),
252 fps->fp, fileno(((FILE *)fps->fp)), fps->fdno);
254 sprintf(be, "??? io %p fp %p fdno %d ???",
255 fps->io, fps->fp, fps->fdno);
263 static void fdstat_enter(FD_t fd, int opx)
265 if (fd == NULL) return;
266 if (fd->stats != NULL)
267 (void) rpmswEnter(fdOp(fd, opx), (ssize_t) 0);
270 static void fdstat_exit(FD_t fd, int opx, ssize_t rc)
272 if (fd == NULL) return;
274 fd->syserrno = errno;
275 else if (rc > 0 && fd->bytesRemain > 0)
279 fd->bytesRemain -= rc;
284 if (fd->stats != NULL)
285 (void) rpmswExit(fdOp(fd, opx), rc);
288 static void fdstat_print(FD_t fd, const char * msg, FILE * fp)
290 static const int usec_scale = (1000*1000);
293 if (fd == NULL || fd->stats == NULL) return;
294 for (opx = 0; opx < 4; opx++) {
295 rpmop op = &fd->stats->ops[opx];
296 if (op->count <= 0) continue;
299 if (msg) fprintf(fp, "%s:", msg);
300 fprintf(fp, "%8d reads, %8ld total bytes in %d.%06d secs\n",
301 op->count, (long)op->bytes,
302 (int)(op->usecs/usec_scale), (int)(op->usecs%usec_scale));
305 if (msg) fprintf(fp, "%s:", msg);
306 fprintf(fp, "%8d writes, %8ld total bytes in %d.%06d secs\n",
307 op->count, (long)op->bytes,
308 (int)(op->usecs/usec_scale), (int)(op->usecs%usec_scale));
318 /* =============================================================== */
319 off_t fdSize(FD_t fd)
325 DBGIO(0, (stderr, "==>\tfdSize(%p) rc %ld\n", fd, (long)rc));
328 switch (fd->urlType) {
331 if (fstat(Fileno(fd), &sb) == 0)
348 if ((nfdno = dup(fdno)) < 0)
350 fd = fdNew(RPMDBG_M("open (fdDup)"));
351 fdSetFdno(fd, nfdno);
352 DBGIO(fd, (stderr, "==> fdDup(%d) fd %p %s\n", fdno, (fd ? fd : NULL), fdbg(fd)));
356 static int fdSeekNot(void * cookie, _libio_pos_t pos, int whence)
358 FD_t fd = c2f(cookie);
359 FDSANE(fd); /* XXX keep gcc quiet */
365 static int fdFileno(void * cookie)
368 if (cookie == NULL) return -2;
370 return fd->fps[0].fdno;
373 FILE * fdGetFILE(FD_t fd)
375 return ((FILE *)fdGetFp(fd));
378 /* =============================================================== */
380 FD_t fdLink(void * cookie, const char * msg)
384 DBGREFS(0, (stderr, "--> fd %p ++ %d %s\n", cookie, FDNREFS(cookie)+1, msg));
388 DBGREFS(fd, (stderr, "--> fd %p ++ %d %s %s\n", fd, fd->nrefs, msg, fdbg(fd)));
395 FD_t fdFree( FD_t fd, const char *msg)
398 DBGREFS(0, (stderr, "--> fd %p -- %d %s\n", fd, FDNREFS(fd), msg));
401 DBGREFS(fd, (stderr, "--> fd %p -- %d %s %s\n", fd, fd->nrefs, msg, fdbg(fd)));
404 fd->stats = _free(fd->stats);
406 fd->digests = rpmDigestBundleFree(fd->digests);
415 FD_t fdNew(const char * msg)
417 FD_t fd = xcalloc(1, sizeof(*fd));
418 if (fd == NULL) /* XXX xmalloc never returns NULL */
423 fd->urlType = URL_IS_UNKNOWN;
426 memset(fd->fps, 0, sizeof(fd->fps));
428 fd->fps[0].io = fdio;
429 fd->fps[0].fp = NULL;
430 fd->fps[0].fdno = -1;
432 fd->bytesRemain = -1;
434 fd->errcookie = NULL;
435 fd->stats = xcalloc(1, sizeof(*fd->stats));
438 return fdLink(fd, msg);
443 static ssize_t fdRead(void * cookie, char * buf, size_t count)
445 FD_t fd = c2f(cookie);
448 if (fd->bytesRemain == 0) return 0; /* XXX simulate EOF */
450 fdstat_enter(fd, FDSTAT_READ);
451 rc = read(fdFileno(fd), buf, (count > fd->bytesRemain ? fd->bytesRemain : count));
452 fdstat_exit(fd, FDSTAT_READ, rc);
454 if (fd->digests && rc > 0) fdUpdateDigests(fd, (void *)buf, rc);
456 DBGIO(fd, (stderr, "==>\tfdRead(%p,%p,%ld) rc %ld %s\n", cookie, buf, (long)count, (long)rc, fdbg(fd)));
463 static ssize_t fdWrite(void * cookie, const char * buf, size_t count)
465 FD_t fd = c2f(cookie);
466 int fdno = fdFileno(fd);
469 if (fd->bytesRemain == 0) return 0; /* XXX simulate EOF */
471 if (fd->digests && count > 0) fdUpdateDigests(fd, (void *)buf, count);
473 if (count == 0) return 0;
475 fdstat_enter(fd, FDSTAT_WRITE);
476 rc = write(fdno, buf, (count > fd->bytesRemain ? fd->bytesRemain : count));
477 fdstat_exit(fd, FDSTAT_WRITE, rc);
479 DBGIO(fd, (stderr, "==>\tfdWrite(%p,%p,%ld) rc %ld %s\n", cookie, buf, (long)count, (long)rc, fdbg(fd)));
484 static int fdSeek(void * cookie, _libio_pos_t pos, int whence)
486 #ifdef USE_COOKIE_SEEK_POINTER
487 _IO_off64_t p = *pos;
491 FD_t fd = c2f(cookie);
494 assert(fd->bytesRemain == -1); /* XXX FIXME fadio only for now */
495 fdstat_enter(fd, FDSTAT_SEEK);
496 rc = lseek(fdFileno(fd), p, whence);
497 fdstat_exit(fd, FDSTAT_SEEK, rc);
499 DBGIO(fd, (stderr, "==>\tfdSeek(%p,%ld,%d) rc %lx %s\n", cookie, (long)p, whence, (unsigned long)rc, fdbg(fd)));
506 static int fdClose( void * cookie)
512 if (cookie == NULL) return -2;
518 fdstat_enter(fd, FDSTAT_CLOSE);
519 rc = ((fdno >= 0) ? close(fdno) : -2);
520 fdstat_exit(fd, FDSTAT_CLOSE, rc);
522 DBGIO(fd, (stderr, "==>\tfdClose(%p) rc %lx %s\n", (fd ? fd : NULL), (unsigned long)rc, fdbg(fd)));
524 fd = fdFree(fd, "open (fdClose)");
530 static FD_t fdOpen(const char *path, int flags, mode_t mode)
535 fdno = open(path, flags, mode);
536 if (fdno < 0) return NULL;
537 if (fcntl(fdno, F_SETFD, FD_CLOEXEC)) {
541 fd = fdNew(RPMDBG_M("open (fdOpen)"));
544 DBGIO(fd, (stderr, "==>\tfdOpen(\"%s\",%x,0%o) %s\n", path, (unsigned)flags, (unsigned)mode, fdbg(fd)));
548 static const struct FDIO_s fdio_s = {
549 fdRead, fdWrite, fdSeek, fdClose, fdLink, fdFree, fdNew, fdFileno,
550 fdOpen, NULL, fdGetFp, NULL
552 static const FDIO_t fdio = &fdio_s ;
554 int fdWritable(FD_t fd, int secs)
559 int msecs = (secs >= 0 ? (1000 * secs) : -1);
562 struct timeval timeout, *tvp = (secs >= 0 ? &timeout : NULL);
567 if ((fdno = fdFileno(fd)) < 0)
568 return -1; /* XXX W2DO? */
573 wrfds.events = POLLOUT;
575 rc = poll(&wrfds, 1, msecs);
581 FD_SET(fdno, &wrfds);
582 rc = select(fdno + 1, NULL, &wrfds, NULL, tvp);
585 if (_rpmio_debug && !(rc == 1 && errno == 0))
586 fprintf(stderr, "*** fdWritable fdno %d rc %d %s\n", fdno, rc, strerror(errno));
601 int fdReadable(FD_t fd, int secs)
606 int msecs = (secs >= 0 ? (1000 * secs) : -1);
609 struct timeval timeout, *tvp = (secs >= 0 ? &timeout : NULL);
614 if ((fdno = fdFileno(fd)) < 0)
615 return -1; /* XXX W2DO? */
620 rdfds.events = POLLIN;
622 rc = poll(&rdfds, 1, msecs);
628 FD_SET(fdno, &rdfds);
629 rc = select(fdno + 1, &rdfds, NULL, NULL, tvp);
646 int ufdCopy(FD_t sfd, FD_t tfd)
654 rc = Fread(buf, sizeof(buf[0]), sizeof(buf), sfd);
662 rc = Fwrite(buf, sizeof(buf[0]), itemsRead, tfd);
665 if (rc != itemsRead) {
670 itemsCopied += itemsRead;
673 DBGIO(sfd, (stderr, "++ copied %d bytes\n", itemsCopied));
679 * Deal with remote url's by fetching them with a helper application
680 * and treat as local file afterwards.
682 * - better error checking + reporting
683 * - curl & friends don't know about hkp://, transform to http?
686 static FD_t urlOpen(const char * url, int flags, mode_t mode)
690 int rc = 1; /* assume failure */
692 fd = rpmMkTempFile(NULL, &dest);
698 rc = urlGetFile(url, dest);
700 fd = fdOpen(dest, flags, mode);
710 static FD_t ufdOpen(const char * url, int flags, mode_t mode)
714 urltype urlType = urlPath(url, &path);
717 fprintf(stderr, "*** ufdOpen(%s,0x%x,0%o)\n", url, (unsigned)flags, (unsigned)mode);
724 fd = urlOpen(url, flags, mode);
725 /* we're dealing with local file when urlOpen() returns */
726 urlType = URL_IS_UNKNOWN;
729 if ((flags & O_ACCMODE) == O_RDWR) {
732 fd = fdDup((flags & O_ACCMODE) == O_WRONLY ?
733 STDOUT_FILENO : STDIN_FILENO);
739 fd = fdOpen(path, flags, mode);
743 if (fd == NULL) return NULL;
746 fd->bytesRemain = -1;
747 fd->urlType = urlType;
749 if (Fileno(fd) < 0) {
753 DBGIO(fd, (stderr, "==>\tufdOpen(\"%s\",%x,0%o) %s\n", url, (unsigned)flags, (unsigned)mode, fdbg(fd)));
757 static const struct FDIO_s ufdio_s = {
758 fdRead, fdWrite, fdSeek, fdClose, fdLink, fdFree, fdNew, fdFileno,
759 ufdOpen, NULL, fdGetFp, NULL
761 static const FDIO_t ufdio = &ufdio_s ;
763 ssize_t timedRead(FD_t fd, void * bufptr, size_t length)
765 return ufdio->read(fd, bufptr, length);
768 /* =============================================================== */
769 /* Support for GZIP library.
775 static void * gzdFileno(FD_t fd)
781 for (i = fd->nfps; i >= 0; i--) {
782 FDSTACK_t * fps = &fd->fps[i];
783 if (fps->io != gzdio)
793 FD_t gzdOpen(const char * path, const char * fmode)
797 if ((gzfile = gzopen(path, fmode)) == NULL)
799 fd = fdNew(RPMDBG_M("open (gzdOpen)"));
800 fdPop(fd); fdPush(fd, gzdio, gzfile, -1);
802 DBGIO(fd, (stderr, "==>\tgzdOpen(\"%s\", \"%s\") fd %p %s\n", path, fmode, (fd ? fd : NULL), fdbg(fd)));
803 return fdLink(fd, RPMDBG_M("gzdOpen"));
806 static FD_t gzdFdopen(void * cookie, const char *fmode)
808 FD_t fd = c2f(cookie);
812 if (fmode == NULL) return NULL;
814 fdSetFdno(fd, -1); /* XXX skip the fdio close */
815 if (fdno < 0) return NULL;
816 gzfile = gzdopen(fdno, fmode);
817 if (gzfile == NULL) return NULL;
819 fdPush(fd, gzdio, gzfile, fdno); /* Push gzdio onto stack */
821 return fdLink(fd, RPMDBG_M("gzdFdopen"));
824 static int gzdFlush(FD_t fd)
827 gzfile = gzdFileno(fd);
828 if (gzfile == NULL) return -2;
829 return gzflush(gzfile, Z_SYNC_FLUSH); /* XXX W2DO? */
832 /* =============================================================== */
833 static ssize_t gzdRead(void * cookie, char * buf, size_t count)
835 FD_t fd = c2f(cookie);
839 if (fd == NULL || fd->bytesRemain == 0) return 0; /* XXX simulate EOF */
841 gzfile = gzdFileno(fd);
842 if (gzfile == NULL) return -2; /* XXX can't happen */
844 fdstat_enter(fd, FDSTAT_READ);
845 rc = gzread(gzfile, buf, count);
846 DBGIO(fd, (stderr, "==>\tgzdRead(%p,%p,%u) rc %lx %s\n", cookie, buf, (unsigned)count, (unsigned long)rc, fdbg(fd)));
849 fd->errcookie = gzerror(gzfile, &zerror);
850 if (zerror == Z_ERRNO) {
851 fd->syserrno = errno;
852 fd->errcookie = strerror(fd->syserrno);
854 } else if (rc >= 0) {
855 fdstat_exit(fd, FDSTAT_READ, rc);
856 if (fd->digests && rc > 0) fdUpdateDigests(fd, (void *)buf, rc);
861 static ssize_t gzdWrite(void * cookie, const char * buf, size_t count)
863 FD_t fd = c2f(cookie);
867 if (fd == NULL || fd->bytesRemain == 0) return 0; /* XXX simulate EOF */
869 if (fd->digests && count > 0) fdUpdateDigests(fd, (void *)buf, count);
871 gzfile = gzdFileno(fd);
872 if (gzfile == NULL) return -2; /* XXX can't happen */
874 fdstat_enter(fd, FDSTAT_WRITE);
875 rc = gzwrite(gzfile, (void *)buf, count);
876 DBGIO(fd, (stderr, "==>\tgzdWrite(%p,%p,%u) rc %lx %s\n", cookie, buf, (unsigned)count, (unsigned long)rc, fdbg(fd)));
879 fd->errcookie = gzerror(gzfile, &zerror);
880 if (zerror == Z_ERRNO) {
881 fd->syserrno = errno;
882 fd->errcookie = strerror(fd->syserrno);
885 fdstat_exit(fd, FDSTAT_WRITE, rc);
890 /* XXX zlib-1.0.4 has not */
891 static int gzdSeek(void * cookie, _libio_pos_t pos, int whence)
893 #ifdef USE_COOKIE_SEEK_POINTER
894 _IO_off64_t p = *pos;
900 FD_t fd = c2f(cookie);
903 if (fd == NULL) return -2;
904 assert(fd->bytesRemain == -1); /* XXX FIXME */
906 gzfile = gzdFileno(fd);
907 if (gzfile == NULL) return -2; /* XXX can't happen */
909 fdstat_enter(fd, FDSTAT_SEEK);
910 rc = gzseek(gzfile, p, whence);
911 DBGIO(fd, (stderr, "==>\tgzdSeek(%p,%ld,%d) rc %lx %s\n", cookie, (long)p, whence, (unsigned long)rc, fdbg(fd)));
914 fd->errcookie = gzerror(gzfile, &zerror);
915 if (zerror == Z_ERRNO) {
916 fd->syserrno = errno;
917 fd->errcookie = strerror(fd->syserrno);
919 } else if (rc >= 0) {
920 fdstat_exit(fd, FDSTAT_SEEK, rc);
928 static int gzdClose( void * cookie)
930 FD_t fd = c2f(cookie);
934 gzfile = gzdFileno(fd);
935 if (gzfile == NULL) return -2; /* XXX can't happen */
937 fdstat_enter(fd, FDSTAT_CLOSE);
938 rc = gzclose(gzfile);
940 /* XXX TODO: preserve fd if errors */
943 DBGIO(fd, (stderr, "==>\tgzdClose(%p) zerror %d %s\n", cookie, rc, fdbg(fd)));
945 fd->errcookie = "gzclose error";
947 fd->syserrno = errno;
948 fd->errcookie = strerror(fd->syserrno);
950 } else if (rc >= 0) {
951 fdstat_exit(fd, FDSTAT_CLOSE, rc);
955 DBGIO(fd, (stderr, "==>\tgzdClose(%p) rc %lx %s\n", cookie, (unsigned long)rc, fdbg(fd)));
957 if (_rpmio_debug || rpmIsDebug()) fdstat_print(fd, "GZDIO", stderr);
959 fd = fdFree(fd, RPMDBG_M("open (gzdClose)"));
963 static const struct FDIO_s gzdio_s = {
964 gzdRead, gzdWrite, gzdSeek, gzdClose, fdLink, fdFree, fdNew, fdFileno,
965 NULL, gzdOpen, gzdFileno, gzdFlush
967 static const FDIO_t gzdio = &gzdio_s ;
969 #endif /* HAVE_ZLIB_H */
971 /* =============================================================== */
972 /* Support for BZIP2 library.
979 # define bzopen BZ2_bzopen
980 # define bzclose BZ2_bzclose
981 # define bzdopen BZ2_bzdopen
982 # define bzerror BZ2_bzerror
983 # define bzflush BZ2_bzflush
984 # define bzread BZ2_bzread
985 # define bzwrite BZ2_bzwrite
986 #endif /* HAVE_BZ2_1_0 */
988 static void * bzdFileno(FD_t fd)
994 for (i = fd->nfps; i >= 0; i--) {
995 FDSTACK_t * fps = &fd->fps[i];
996 if (fps->io != bzdio)
1005 static FD_t bzdOpen(const char * path, const char * mode)
1009 if ((bzfile = bzopen(path, mode)) == NULL)
1011 fd = fdNew(RPMDBG_M("open (bzdOpen)"));
1012 fdPop(fd); fdPush(fd, bzdio, bzfile, -1);
1013 return fdLink(fd, RPMDBG_M("bzdOpen"));
1016 static FD_t bzdFdopen(void * cookie, const char * fmode)
1018 FD_t fd = c2f(cookie);
1022 if (fmode == NULL) return NULL;
1023 fdno = fdFileno(fd);
1024 fdSetFdno(fd, -1); /* XXX skip the fdio close */
1025 if (fdno < 0) return NULL;
1026 bzfile = bzdopen(fdno, fmode);
1027 if (bzfile == NULL) return NULL;
1029 fdPush(fd, bzdio, bzfile, fdno); /* Push bzdio onto stack */
1031 return fdLink(fd, RPMDBG_M("bzdFdopen"));
1034 static int bzdFlush(FD_t fd)
1036 return bzflush(bzdFileno(fd));
1039 /* =============================================================== */
1040 static ssize_t bzdRead(void * cookie, char * buf, size_t count)
1042 FD_t fd = c2f(cookie);
1046 if (fd->bytesRemain == 0) return 0; /* XXX simulate EOF */
1047 bzfile = bzdFileno(fd);
1048 fdstat_enter(fd, FDSTAT_READ);
1050 rc = bzread(bzfile, buf, count);
1054 fd->errcookie = bzerror(bzfile, &zerror);
1055 } else if (rc >= 0) {
1056 fdstat_exit(fd, FDSTAT_READ, rc);
1057 if (fd->digests && rc > 0) fdUpdateDigests(fd, (void *)buf, rc);
1062 static ssize_t bzdWrite(void * cookie, const char * buf, size_t count)
1064 FD_t fd = c2f(cookie);
1068 if (fd->bytesRemain == 0) return 0; /* XXX simulate EOF */
1070 if (fd->digests && count > 0) fdUpdateDigests(fd, (void *)buf, count);
1072 bzfile = bzdFileno(fd);
1073 fdstat_enter(fd, FDSTAT_WRITE);
1074 rc = bzwrite(bzfile, (void *)buf, count);
1077 fd->errcookie = bzerror(bzfile, &zerror);
1078 } else if (rc > 0) {
1079 fdstat_exit(fd, FDSTAT_WRITE, rc);
1084 static int bzdClose( void * cookie)
1086 FD_t fd = c2f(cookie);
1090 bzfile = bzdFileno(fd);
1092 if (bzfile == NULL) return -2;
1093 fdstat_enter(fd, FDSTAT_CLOSE);
1096 rc = 0; /* XXX FIXME */
1098 /* XXX TODO: preserve fd if errors */
1103 fd->errcookie = bzerror(bzfile, &zerror);
1104 } else if (rc >= 0) {
1105 fdstat_exit(fd, FDSTAT_CLOSE, rc);
1109 DBGIO(fd, (stderr, "==>\tbzdClose(%p) rc %lx %s\n", cookie, (unsigned long)rc, fdbg(fd)));
1111 if (_rpmio_debug || rpmIsDebug()) fdstat_print(fd, "BZDIO", stderr);
1113 fd = fdFree(fd, RPMDBG_M("open (bzdClose)"));
1117 static const struct FDIO_s bzdio_s = {
1118 bzdRead, bzdWrite, fdSeekNot, bzdClose, fdLink, fdFree, fdNew, fdFileno,
1119 NULL, bzdOpen, bzdFileno, bzdFlush
1121 static const FDIO_t bzdio = &bzdio_s ;
1123 #endif /* HAVE_BZLIB_H */
1125 /* =============================================================== */
1126 static const char * getFdErrstr (FD_t fd)
1128 const char *errstr = NULL;
1131 if (fdGetIo(fd) == gzdio) {
1132 errstr = fd->errcookie;
1134 #endif /* HAVE_ZLIB_H */
1137 if (fdGetIo(fd) == bzdio) {
1138 errstr = fd->errcookie;
1140 #endif /* HAVE_BZLIB_H */
1142 if (fdGetIo(fd) == xzdio || fdGetIo(fd) == lzdio) {
1143 errstr = fd->errcookie;
1145 #endif /* HAVE_LZMA_H */
1147 errstr = (fd->syserrno ? strerror(fd->syserrno) : "");
1153 /* =============================================================== */
1154 /* Support for LZMA library.
1159 #include <sys/types.h>
1160 #include <inttypes.h>
1163 #define kBufferSize (1 << 15)
1165 typedef struct lzfile {
1167 uint8_t buf[kBufferSize];
1178 static LZFILE *lzopen_internal(const char *path, const char *mode, int fd, int xz)
1180 int level = 7; /* Use XZ's default compression level if unspecified */
1185 lzma_stream init_strm = LZMA_STREAM_INIT;
1187 for (; *mode; mode++) {
1190 else if (*mode == 'r')
1192 else if (*mode >= '1' && *mode <= '9')
1193 level = *mode - '0';
1196 fp = fdopen(fd, encoding ? "w" : "r");
1198 fp = fopen(path, encoding ? "w" : "r");
1201 lzfile = calloc(1, sizeof(*lzfile));
1208 lzfile->encoding = encoding;
1210 lzfile->strm = init_strm;
1213 ret = lzma_easy_encoder(&lzfile->strm, level, LZMA_CHECK_SHA256);
1215 lzma_options_lzma options;
1216 lzma_lzma_preset(&options, level);
1217 ret = lzma_alone_encoder(&lzfile->strm, &options);
1219 } else { /* lzma_easy_decoder_memusage(level) is not ready yet, use hardcoded limit for now */
1220 ret = lzma_auto_decoder(&lzfile->strm, 100<<20, 0);
1222 if (ret != LZMA_OK) {
1230 static LZFILE *xzopen(const char *path, const char *mode)
1232 return lzopen_internal(path, mode, -1, 1);
1235 static LZFILE *xzdopen(int fd, const char *mode)
1239 return lzopen_internal(0, mode, fd, 1);
1242 static LZFILE *lzopen(const char *path, const char *mode)
1244 return lzopen_internal(path, mode, -1, 0);
1247 static LZFILE *lzdopen(int fd, const char *mode)
1251 return lzopen_internal(0, mode, fd, 0);
1254 static int lzflush(LZFILE *lzfile)
1256 return fflush(lzfile->file);
1259 static int lzclose(LZFILE *lzfile)
1267 if (lzfile->encoding) {
1269 lzfile->strm.avail_out = kBufferSize;
1270 lzfile->strm.next_out = lzfile->buf;
1271 ret = lzma_code(&lzfile->strm, LZMA_FINISH);
1272 if (ret != LZMA_OK && ret != LZMA_STREAM_END)
1274 n = kBufferSize - lzfile->strm.avail_out;
1275 if (n && fwrite(lzfile->buf, 1, n, lzfile->file) != n)
1277 if (ret == LZMA_STREAM_END)
1281 lzma_end(&lzfile->strm);
1282 rc = fclose(lzfile->file);
1287 static ssize_t lzread(LZFILE *lzfile, void *buf, size_t len)
1292 if (!lzfile || lzfile->encoding)
1296 lzfile->strm.next_out = buf;
1297 lzfile->strm.avail_out = len;
1299 if (!lzfile->strm.avail_in) {
1300 lzfile->strm.next_in = lzfile->buf;
1301 lzfile->strm.avail_in = fread(lzfile->buf, 1, kBufferSize, lzfile->file);
1302 if (!lzfile->strm.avail_in)
1305 ret = lzma_code(&lzfile->strm, LZMA_RUN);
1306 if (ret == LZMA_STREAM_END) {
1308 return len - lzfile->strm.avail_out;
1312 if (!lzfile->strm.avail_out)
1319 static ssize_t lzwrite(LZFILE *lzfile, void *buf, size_t len)
1323 if (!lzfile || !lzfile->encoding)
1327 lzfile->strm.next_in = buf;
1328 lzfile->strm.avail_in = len;
1330 lzfile->strm.next_out = lzfile->buf;
1331 lzfile->strm.avail_out = kBufferSize;
1332 ret = lzma_code(&lzfile->strm, LZMA_RUN);
1335 n = kBufferSize - lzfile->strm.avail_out;
1336 if (n && fwrite(lzfile->buf, 1, n, lzfile->file) != n)
1338 if (!lzfile->strm.avail_in)
1343 /* =============================================================== */
1345 static void * lzdFileno(FD_t fd)
1351 for (i = fd->nfps; i >= 0; i--) {
1352 FDSTACK_t * fps = &fd->fps[i];
1353 if (fps->io != xzdio && fps->io != lzdio)
1362 static FD_t xzdOpen(const char * path, const char * mode)
1366 if ((lzfile = xzopen(path, mode)) == NULL)
1368 fd = fdNew("open (xzdOpen)");
1369 fdPop(fd); fdPush(fd, xzdio, lzfile, -1);
1370 return fdLink(fd, "xzdOpen");
1373 static FD_t xzdFdopen(void * cookie, const char * fmode)
1375 FD_t fd = c2f(cookie);
1379 if (fmode == NULL) return NULL;
1380 fdno = fdFileno(fd);
1381 fdSetFdno(fd, -1); /* XXX skip the fdio close */
1382 if (fdno < 0) return NULL;
1383 lzfile = xzdopen(fdno, fmode);
1384 if (lzfile == NULL) return NULL;
1385 fdPush(fd, xzdio, lzfile, fdno);
1386 return fdLink(fd, "xzdFdopen");
1389 static FD_t lzdOpen(const char * path, const char * mode)
1393 if ((lzfile = lzopen(path, mode)) == NULL)
1395 fd = fdNew("open (lzdOpen)");
1396 fdPop(fd); fdPush(fd, xzdio, lzfile, -1);
1397 return fdLink(fd, "lzdOpen");
1400 static FD_t lzdFdopen(void * cookie, const char * fmode)
1402 FD_t fd = c2f(cookie);
1406 if (fmode == NULL) return NULL;
1407 fdno = fdFileno(fd);
1408 fdSetFdno(fd, -1); /* XXX skip the fdio close */
1409 if (fdno < 0) return NULL;
1410 lzfile = lzdopen(fdno, fmode);
1411 if (lzfile == NULL) return NULL;
1412 fdPush(fd, xzdio, lzfile, fdno);
1413 return fdLink(fd, "lzdFdopen");
1416 static int lzdFlush(FD_t fd)
1418 return lzflush(lzdFileno(fd));
1421 /* =============================================================== */
1422 static ssize_t lzdRead(void * cookie, char * buf, size_t count)
1424 FD_t fd = c2f(cookie);
1428 if (fd->bytesRemain == 0) return 0; /* XXX simulate EOF */
1429 lzfile = lzdFileno(fd);
1430 fdstat_enter(fd, FDSTAT_READ);
1432 rc = lzread(lzfile, buf, count);
1434 fd->errcookie = "Lzma: decoding error";
1435 } else if (rc >= 0) {
1436 fdstat_exit(fd, FDSTAT_READ, rc);
1437 if (fd->digests && rc > 0) fdUpdateDigests(fd, (void *)buf, rc);
1442 static ssize_t lzdWrite(void * cookie, const char * buf, size_t count)
1444 FD_t fd = c2f(cookie);
1448 if (fd == NULL || fd->bytesRemain == 0) return 0; /* XXX simulate EOF */
1450 if (fd->digests && count > 0) fdUpdateDigests(fd, (void *)buf, count);
1452 lzfile = lzdFileno(fd);
1454 fdstat_enter(fd, FDSTAT_WRITE);
1455 rc = lzwrite(lzfile, (void *)buf, count);
1457 fd->errcookie = "Lzma: encoding error";
1458 } else if (rc > 0) {
1459 fdstat_exit(fd, FDSTAT_WRITE, rc);
1464 static int lzdClose(void * cookie)
1466 FD_t fd = c2f(cookie);
1470 lzfile = lzdFileno(fd);
1472 if (lzfile == NULL) return -2;
1473 fdstat_enter(fd, FDSTAT_CLOSE);
1474 rc = lzclose(lzfile);
1476 /* XXX TODO: preserve fd if errors */
1480 fd->errcookie = strerror(ferror(lzfile->file));
1481 } else if (rc >= 0) {
1482 fdstat_exit(fd, FDSTAT_CLOSE, rc);
1486 DBGIO(fd, (stderr, "==>\tlzdClose(%p) rc %lx %s\n", cookie, (unsigned long)rc, fdbg(fd)));
1488 if (_rpmio_debug || rpmIsDebug()) fdstat_print(fd, "XZDIO", stderr);
1490 fd = fdFree(fd, "open (lzdClose)");
1494 static struct FDIO_s xzdio_s = {
1495 lzdRead, lzdWrite, fdSeekNot, lzdClose, NULL, NULL, NULL, fdFileno,
1496 NULL, xzdOpen, lzdFileno, lzdFlush
1498 static const FDIO_t xzdio = &xzdio_s;
1500 static struct FDIO_s lzdio_s = {
1501 lzdRead, lzdWrite, fdSeekNot, lzdClose, NULL, NULL, NULL, fdFileno,
1502 NULL, lzdOpen, lzdFileno, lzdFlush
1504 static const FDIO_t lzdio = &lzdio_s;
1506 #endif /* HAVE_LZMA_H */
1508 /* =============================================================== */
1510 const char *Fstrerror(FD_t fd)
1513 return (errno ? strerror(errno) : "");
1515 return getFdErrstr(fd);
1518 #define FDIOVEC(_fd, _vec) \
1519 ((fdGetIo(_fd) && fdGetIo(_fd)->_vec) ? fdGetIo(_fd)->_vec : NULL)
1521 ssize_t Fread(void *buf, size_t size, size_t nmemb, FD_t fd) {
1522 fdio_read_function_t _read;
1526 DBGIO(fd, (stderr, "==> Fread(%p,%u,%u,%p) %s\n", buf, (unsigned)size, (unsigned)nmemb, (fd ? fd : NULL), fdbg(fd)));
1528 if (fdGetIo(fd) == fpio) {
1529 rc = fread(buf, size, nmemb, fdGetFILE(fd));
1533 _read = FDIOVEC(fd, read);
1535 rc = (_read ? (*_read) (fd, buf, size * nmemb) : -2);
1539 ssize_t Fwrite(const void *buf, size_t size, size_t nmemb, FD_t fd)
1541 fdio_write_function_t _write;
1545 DBGIO(fd, (stderr, "==> Fwrite(%p,%u,%u,%p) %s\n", buf, (unsigned)size, (unsigned)nmemb, (fd ? fd : NULL), fdbg(fd)));
1547 if (fdGetIo(fd) == fpio) {
1548 rc = fwrite(buf, size, nmemb, fdGetFILE(fd));
1552 _write = FDIOVEC(fd, write);
1554 rc = (_write ? _write(fd, buf, size * nmemb) : -2);
1558 int Fseek(FD_t fd, _libio_off_t offset, int whence) {
1559 fdio_seek_function_t _seek;
1560 #ifdef USE_COOKIE_SEEK_POINTER
1561 _IO_off64_t o64 = offset;
1562 _libio_pos_t pos = &o64;
1564 _libio_pos_t pos = offset;
1570 DBGIO(fd, (stderr, "==> Fseek(%p,%ld,%d) %s\n", fd, (long)offset, whence, fdbg(fd)));
1572 if (fdGetIo(fd) == fpio) {
1576 rc = fseek(fp, offset, whence);
1580 _seek = FDIOVEC(fd, seek);
1582 rc = (_seek ? _seek(fd, pos, whence) : -2);
1591 DBGIO(fd, (stderr, "==> Fclose(%p) %s\n", (fd ? fd : NULL), fdbg(fd)));
1593 fd = fdLink(fd, RPMDBG_M("Fclose"));
1594 while (fd->nfps >= 0) {
1595 FDSTACK_t * fps = &fd->fps[fd->nfps];
1597 if (fps->io == fpio) {
1606 fd = fdFree(fd, RPMDBG_M("fopencookie (Fclose)"));
1610 fdio_close_function_t _close = FDIOVEC(fd, close);
1611 rc = _close ? _close(fd) : -2;
1619 fd = fdFree(fd, RPMDBG_M("Fclose"));
1624 * Convert stdio fmode to open(2) mode, filtering out zlib/bzlib flags.
1625 * returns stdio[0] = NUL on error.
1627 * - gzopen: [0-9] is compression level
1628 * - gzopen: 'f' is filtered (Z_FILTERED)
1629 * - gzopen: 'h' is Huffman encoding (Z_HUFFMAN_ONLY)
1630 * - bzopen: [1-9] is block size (modulo 100K)
1631 * - bzopen: 's' is smallmode
1632 * - HACK: '.' terminates, rest is type of I/O
1634 static void cvtfmode (const char *m,
1635 char *stdio, size_t nstdio,
1636 char *other, size_t nother,
1637 const char **end, int * f)
1644 flags |= O_WRONLY | O_CREAT | O_APPEND;
1645 if (--nstdio > 0) *stdio++ = *m;
1648 flags |= O_WRONLY | O_CREAT | O_TRUNC;
1649 if (--nstdio > 0) *stdio++ = *m;
1653 if (--nstdio > 0) *stdio++ = *m;
1662 while ((c = *m++) != '\0') {
1667 flags &= ~(O_RDONLY|O_WRONLY);
1669 if (--nstdio > 0) *stdio++ = c;
1673 if (--nstdio > 0) *stdio++ = c;
1678 if (--nstdio > 0) *stdio++ = c;
1682 if (--nother > 0) *other++ = c;
1689 *stdio = *other = '\0';
1691 *end = (*m != '\0' ? m : NULL);
1697 #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0
1698 /* XXX retrofit glibc-2.1.x typedef on glibc-2.0.x systems */
1699 typedef _IO_cookie_io_functions_t cookie_io_functions_t;
1703 FD_t Fdopen(FD_t ofd, const char *fmode)
1705 char stdio[20], other[20], zstdio[20];
1706 const char *end = NULL;
1711 fprintf(stderr, "*** Fdopen(%p,%s) %s\n", fd, fmode, fdbg(fd));
1717 cvtfmode(fmode, stdio, sizeof(stdio), other, sizeof(other), &end, NULL);
1718 if (stdio[0] == '\0')
1721 strncat(zstdio, stdio, sizeof(zstdio) - strlen(zstdio));
1722 strncat(zstdio, other, sizeof(zstdio) - strlen(zstdio));
1724 if (end == NULL && other[0] == '\0')
1728 if (rstreq(end, "fdio")) {
1731 } else if (rstreq(end, "gzdio") || rstreq(end, "gzip")) {
1733 fd = gzdFdopen(fd, zstdio);
1736 } else if (rstreq(end, "bzdio") || rstreq(end, "bzip2")) {
1738 fd = bzdFdopen(fd, zstdio);
1741 } else if (rstreq(end, "xzdio") || rstreq(end, "xz")) {
1743 fd = xzdFdopen(fd, zstdio);
1744 } else if (rstreq(end, "lzdio") || rstreq(end, "lzma")) {
1746 fd = lzdFdopen(fd, zstdio);
1748 } else if (rstreq(end, "ufdio")) {
1750 } else if (rstreq(end, "fpio")) {
1753 int fdno = Fileno(fd);
1754 FILE * fp = fdopen(fdno, stdio);
1756 fprintf(stderr, "*** Fdopen fpio fp %p\n", (void *)fp);
1759 /* XXX gzdio/bzdio use fp for private data */
1760 if (fdGetFp(fd) == NULL)
1762 fdPush(fd, fpio, fp, fdno); /* Push fpio onto stack */
1765 } else if (other[0] != '\0') {
1766 for (end = other; *end && strchr("0123456789fh", *end); end++)
1770 fd = gzdFdopen(fd, zstdio);
1780 { cookie_io_functions_t ciof;
1781 ciof.read = iof->read;
1782 ciof.write = iof->write;
1783 ciof.seek = iof->seek;
1784 ciof.close = iof->close;
1785 fp = fopencookie(fd, stdio, ciof);
1786 DBGIO(fd, (stderr, "==> fopencookie(%p,\"%s\",*%p) returns fp %p\n", fd, stdio, iof, fp));
1791 /* XXX gzdio/bzdio use fp for private data */
1792 if (fdGetFp(fd) == NULL)
1794 fdPush(fd, fpio, fp, fileno(fp)); /* Push fpio onto stack */
1795 fd = fdLink(fd, RPMDBG_M("fopencookie"));
1799 DBGIO(fd, (stderr, "==> Fdopen(%p,\"%s\") returns fd %p %s\n", ofd, fmode, (fd ? fd : NULL), fdbg(fd)));
1803 FD_t Fopen(const char *path, const char *fmode)
1805 char stdio[20], other[20];
1806 const char *end = NULL;
1807 mode_t perms = 0666;
1811 if (path == NULL || fmode == NULL)
1815 cvtfmode(fmode, stdio, sizeof(stdio), other, sizeof(other), &end, &flags);
1816 if (stdio[0] == '\0')
1819 if (end == NULL || rstreq(end, "fdio")) {
1821 fprintf(stderr, "*** Fopen fdio path %s fmode %s\n", path, fmode);
1822 fd = fdOpen(path, flags, perms);
1823 if (fdFileno(fd) < 0) {
1824 if (fd) (void) fdClose(fd);
1828 /* XXX gzdio and bzdio here too */
1830 switch (urlIsURL(path)) {
1837 case URL_IS_UNKNOWN:
1839 fprintf(stderr, "*** Fopen ufdio path %s fmode %s\n", path, fmode);
1840 fd = ufdOpen(path, flags, perms);
1841 if (fd == NULL || !(fdFileno(fd) >= 0))
1846 fprintf(stderr, "*** Fopen WTFO path %s fmode %s\n", path, fmode);
1854 fd = Fdopen(fd, fmode);
1861 if (fd == NULL) return -1;
1862 if (fdGetIo(fd) == fpio)
1863 return fflush(fdGetFILE(fd));
1867 if (vh && fdGetIo(fd) == gzdio)
1868 return gzdFlush(vh);
1871 if (vh && fdGetIo(fd) == bzdio)
1872 return bzdFlush(vh);
1875 if (vh && (fdGetIo(fd) == xzdio || fdGetIo(fd) == lzdio))
1876 return lzdFlush(vh);
1878 /* FIXME: If we get here, something went wrong above */
1882 off_t Ftell(FD_t fd)
1885 off_t pos = -2; /* assume not implemented */
1887 if (fd == NULL) return -1;
1889 /* this wont work correctly for compressed types */
1890 if (iot == fpio || iot == fdio || iot == ufdio) {
1891 pos = lseek(Fileno(fd), 0, SEEK_CUR);
1901 if (fd == NULL) return -1;
1902 for (i = fd->nfps; rc == 0 && i >= 0; i--) {
1903 FDSTACK_t * fps = &fd->fps[i];
1906 if (fps->io == fpio) {
1907 ec = ferror(fdGetFILE(fd));
1909 } else if (fps->io == gzdio) {
1910 ec = (fd->syserrno || fd->errcookie != NULL) ? -1 : 0;
1911 i--; /* XXX fdio under gzdio always has fdno == -1 */
1914 } else if (fps->io == bzdio) {
1915 ec = (fd->syserrno || fd->errcookie != NULL) ? -1 : 0;
1916 i--; /* XXX fdio under bzdio always has fdno == -1 */
1919 } else if (fps->io == xzdio || fps->io == lzdio) {
1920 ec = (fd->syserrno || fd->errcookie != NULL) ? -1 : 0;
1921 i--; /* XXX fdio under xzdio/lzdio always has fdno == -1 */
1924 /* XXX need to check ufdio/gzdio/bzdio/fdio errors correctly. */
1925 ec = (fdFileno(fd) < 0 ? -1 : 0);
1931 DBGIO(fd, (stderr, "==> Ferror(%p) rc %d %s\n", fd, rc, fdbg(fd)));
1939 if (fd == NULL) return -1;
1940 for (i = fd->nfps ; rc == -1 && i >= 0; i--) {
1941 rc = fd->fps[i].fdno;
1944 DBGIO(fd, (stderr, "==> Fileno(%p) rc %d %s\n", (fd ? fd : NULL), rc, fdbg(fd)));
1948 /* XXX this is naive */
1949 int Fcntl(FD_t fd, int op, void *lip)
1951 return fcntl(Fileno(fd), op, lip);
1954 rpmop fdOp(FD_t fd, fdOpX opx)
1958 if (fd != NULL && fd->stats != NULL && opx >= 0 && opx < FDSTAT_MAX)
1959 op = fd->stats->ops + opx;
1963 int rpmioSlurp(const char * fn, uint8_t ** bp, ssize_t * blenp)
1965 static const ssize_t blenmax = (32 * BUFSIZ);
1972 fd = Fopen(fn, "r.ufdio");
1973 if (fd == NULL || Ferror(fd)) {
1979 blen = (size >= 0 ? size : blenmax);
1982 b = xmalloc(blen+1);
1984 nb = Fread(b, sizeof(*b), blen, fd);
1985 if (Ferror(fd) || (size > 0 && nb != blen)) {
1989 if (blen == blenmax && nb < blen) {
1991 b = xrealloc(b, blen+1);
1997 if (fd) (void) Fclose(fd);
2006 else if (b) free(b);
2008 if (blenp) *blenp = blen;
2013 static const struct FDIO_s fpio_s = {
2014 fdRead, fdWrite, fdSeek, fdClose, fdLink, fdFree, fdNew, fdFileno,
2015 ufdOpen, NULL, fdGetFp, NULL
2017 static const FDIO_t fpio = &fpio_s ;
2019 void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int flags)
2021 if (fd->digests == NULL) {
2022 fd->digests = rpmDigestBundleNew();
2024 fdstat_enter(fd, FDSTAT_DIGEST);
2025 rpmDigestBundleAdd(fd->digests, hashalgo, flags);
2026 fdstat_exit(fd, FDSTAT_DIGEST, (ssize_t) 0);
2029 static void fdUpdateDigests(FD_t fd, const unsigned char * buf, size_t buflen)
2031 if (fd && fd->digests) {
2032 fdstat_enter(fd, FDSTAT_DIGEST);
2033 rpmDigestBundleUpdate(fd->digests, buf, buflen);
2034 fdstat_exit(fd, FDSTAT_DIGEST, (ssize_t) buflen);
2038 void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo,
2043 if (fd && fd->digests) {
2044 fdstat_enter(fd, FDSTAT_DIGEST);
2045 rpmDigestBundleFinal(fd->digests, hashalgo, datap, lenp, asAscii);
2046 fdstat_exit(fd, FDSTAT_DIGEST, (ssize_t) 0);