8 #if defined(HAVE_STDBOOL_H) || defined(__LCLINT__)
11 typedef enum {
true = 1,
false = 0 }
bool;
18 #if defined(WITH_ZLIB)
28 #define GZDONLY(fd) assert(fdGetIo(fd) == gzdio)
30 typedef struct cpio_state_s {
37 #define RSYNC_WIN 4096
39 typedef struct rsync_state_s {
42 unsigned char win[RSYNC_WIN];
45 typedef struct rpmGZFILE_s {
47 struct rsync_state_s rs;
48 struct cpio_state_s cs;
59 static int enable_rsync = 1;
63 #define CPIO_NEWC_MAGIC "070701"
64 #define PHYS_HDR_SIZE 110
66 #define OFFSET_MODE (sizeof(CPIO_NEWC_MAGIC)-1 + 1*8)
67 #define OFFSET_NLNK (sizeof(CPIO_NEWC_MAGIC)-1 + 4*8)
68 #define OFFSET_SIZE (sizeof(CPIO_NEWC_MAGIC)-1 + 6*8)
74 if (c >=
'0' && c <=
'9')
75 return (
int)(c -
'0');
76 else if (c >=
'a' && c <=
'f')
77 return (
int)(c -
'a') + 10;
78 else if (c >=
'A' && c <=
'F')
79 return (
int)(c -
'A') + 10;
84 bool cpio_next(cpio_state s,
unsigned char c)
94 else if (s->n >= OFFSET_MODE && s->n < OFFSET_MODE+8) {
95 if (s->n == OFFSET_MODE)
101 else if (s->n >= OFFSET_NLNK && s->n < OFFSET_NLNK+8) {
102 if (s->n == OFFSET_NLNK)
108 else if (s->n >= OFFSET_SIZE && s->n < OFFSET_SIZE+8) {
109 if (s->n == OFFSET_SIZE)
118 if (!S_ISREG(s->mode) || s->nlnk != 1)
135 bool rsync_next(rsync_state s,
unsigned char c)
140 if (s->n < RSYNC_WIN) {
145 i = s->n++ % RSYNC_WIN;
149 if (s->sum % RSYNC_WIN == 0) {
160 bool sync_hint(rpmGZFILE rpmgz,
unsigned char c)
167 cpio_hint = cpio_next(&rpmgz->cs, c);
170 rpmgz->rs.n = rpmgz->rs.sum = 0;
171 if (rpmgz->nb >= 2*CHUNK)
174 if (rpmgz->cs.size < CHUNK)
177 if (rpmgz->nb < CHUNK/2)
184 rsync_hint = rsync_next(&rpmgz->rs, c);
187 assert(rpmgz->nb >= RSYNC_WIN);
195 rsyncable_gzwrite(rpmGZFILE rpmgz,
const unsigned char *
const buf,
const size_t len)
200 ssize_t n_written = 0;
201 const unsigned char *begin = buf;
204 for (i = 0; i <
len; i++) {
205 if (!sync_hint(rpmgz, buf[i]))
207 n = i + 1 - (begin - buf);
208 rc = gzwrite(rpmgz->gz, begin, (
unsigned)n);
210 return (n_written ? n_written : rc);
215 rc = gzflush(rpmgz->gz, Z_SYNC_FLUSH);
217 return (n_written ? n_written : rc);
219 if (begin < buf + len) {
220 n = len - (begin - buf);
221 rc = gzwrite(rpmgz->gz, begin, (
unsigned)n);
223 return (n_written ? n_written : rc);
232 static inline void * gzdFileno(
FD_t fd)
239 for (i = fd->
nfps; i >= 0; i--) {
251 FD_t gzdOpen(
const char * path,
const char * fmode)
257 mode_t
mode = (fmode && fmode[0] ==
'w' ? O_WRONLY : O_RDONLY);
259 rpmgz = (rpmGZFILE)
xcalloc(1,
sizeof(*rpmgz));
260 rpmgz->gz = gzopen(path, fmode);
261 if (rpmgz->gz == NULL) {
262 rpmgz =
_free(rpmgz);
265 fd =
fdNew(
"open (gzdOpen)");
269 DBGIO(fd, (stderr,
"==>\tgzdOpen(\"%s\", \"%s\") fd %p %s\n", path, fmode, (fd ? fd : NULL),
fdbg(fd)));
270 return fdLink(fd,
"gzdOpen");
273 static FD_t gzdFdopen(
void * cookie,
const char *fmode)
281 if (fmode == NULL)
return NULL;
284 if (fdno < 0)
return NULL;
285 rpmgz = (rpmGZFILE)
xcalloc(1,
sizeof(*rpmgz));
286 rpmgz->gz = gzdopen(fdno, fmode);
287 if (rpmgz->gz == NULL) {
288 rpmgz =
_free(rpmgz);
294 return fdLink(fd,
"gzdFdopen");
297 static int gzdFlush(
void * cookie)
302 rpmgz = (rpmGZFILE) gzdFileno(fd);
303 if (rpmgz == NULL)
return -2;
304 return gzflush(rpmgz->gz, Z_SYNC_FLUSH);
309 static ssize_t gzdRead(
void * cookie,
char * buf,
size_t count)
319 rpmgz = (rpmGZFILE) gzdFileno(fd);
320 if (rpmgz == NULL)
return -2;
323 rc = gzread(rpmgz->gz, buf, (
unsigned)count);
324 DBGIO(fd, (stderr,
"==>\tgzdRead(%p,%p,%u) rc %lx %s\n", cookie, buf, (
unsigned)count, (
unsigned long)rc,
fdbg(fd)));
327 fd->
errcookie = gzerror(rpmgz->gz, &zerror);
328 if (zerror == Z_ERRNO) {
340 static ssize_t gzdWrite(
void * cookie,
const char * buf,
size_t count)
352 rpmgz = (rpmGZFILE) gzdFileno(fd);
353 if (rpmgz == NULL)
return -2;
357 rc = rsyncable_gzwrite(rpmgz, (
const unsigned char *)buf, (
unsigned)count);
359 rc = gzwrite(rpmgz->gz, (
void *)buf, (
unsigned)count);
360 DBGIO(fd, (stderr,
"==>\tgzdWrite(%p,%p,%u) rc %lx %s\n", cookie, buf, (
unsigned)count, (
unsigned long)rc,
fdbg(fd)));
361 if (rc < (ssize_t)count) {
363 fd->
errcookie = gzerror(rpmgz->gz, &zerror);
364 if (zerror == Z_ERRNO) {
376 static int gzdSeek(
void * cookie,
_libio_pos_t pos,
int whence)
381 #if defined(HAVE_GZSEEK)
382 #ifdef USE_COOKIE_SEEK_POINTER
383 _IO_off64_t p = *pos;
390 if (fd == NULL)
return -2;
393 rpmgz = (rpmGZFILE) gzdFileno(fd);
394 if (rpmgz == NULL)
return -2;
397 rc = gzseek(rpmgz->gz, (
long)p, whence);
398 DBGIO(fd, (stderr,
"==>\tgzdSeek(%p,%ld,%d) rc %lx %s\n", cookie, (
long)p, whence, (
unsigned long)rc,
fdbg(fd)));
401 fd->
errcookie = gzerror(rpmgz->gz, &zerror);
402 if (zerror == Z_ERRNO) {
415 static int gzdClose(
void * cookie)
423 rpmgz = (rpmGZFILE) gzdFileno(fd);
424 if (rpmgz == NULL)
return -2;
428 rc = gzclose(rpmgz->gz);
432 rpmgz =
_free(rpmgz);
438 DBGIO(fd, (stderr,
"==>\tgzdClose(%p) zerror %d %s\n", cookie, rc,
fdbg(fd)));
445 }
else if (rc >= 0) {
450 DBGIO(fd, (stderr,
"==>\tgzdClose(%p) rc %lx %s\n", cookie, (
unsigned long)rc,
fdbg(fd)));
454 fd =
fdFree(fd,
"open (gzdClose)");
459 static struct FDIO_s gzdio_s = {
460 gzdRead, gzdWrite, gzdSeek, gzdClose, gzdOpen, gzdFdopen, gzdFlush,
const char const double d
static void fdstat_enter(FD_t fd, int opx)
const char const char size_t len
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.
void * xcalloc(size_t nmemb, size_t size)
FD_t fdFree(FD_t fd, const char *msg)
static void fdstat_print(FD_t fd, const char *msg, FILE *fp)
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)
const char const char size_t size
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
static FD_t c2f(void *cookie)
static void fdstat_exit(FD_t fd, int opx, ssize_t rc)