8 #if defined(NOTYET) || 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;
54 static int enable_rsync = 1;
58 #define CPIO_NEWC_MAGIC "070701"
59 #define PHYS_HDR_SIZE 110
61 #define OFFSET_MODE (sizeof(CPIO_NEWC_MAGIC)-1 + 1*8)
62 #define OFFSET_NLNK (sizeof(CPIO_NEWC_MAGIC)-1 + 4*8)
63 #define OFFSET_SIZE (sizeof(CPIO_NEWC_MAGIC)-1 + 6*8)
69 if (c >=
'0' && c <=
'9')
70 return (
int)(c -
'0');
71 else if (c >=
'a' && c <=
'f')
72 return (
int)(c -
'a') + 10;
73 else if (c >=
'A' && c <=
'F')
74 return (
int)(c -
'A') + 10;
79 bool cpio_next(cpio_state s,
unsigned char c)
89 else if (s->n >= OFFSET_MODE && s->n < OFFSET_MODE+8) {
90 if (s->n == OFFSET_MODE)
96 else if (s->n >= OFFSET_NLNK && s->n < OFFSET_NLNK+8) {
97 if (s->n == OFFSET_NLNK)
103 else if (s->n >= OFFSET_SIZE && s->n < OFFSET_SIZE+8) {
104 if (s->n == OFFSET_SIZE)
113 if (!S_ISREG(s->mode) || s->nlnk != 1)
130 bool rsync_next(rsync_state s,
unsigned char c)
135 if (s->n < RSYNC_WIN) {
140 i = s->n++ % RSYNC_WIN;
144 if (s->sum % RSYNC_WIN == 0) {
155 bool sync_hint(rpmGZFILE rpmgz,
unsigned char c)
162 cpio_hint = cpio_next(&rpmgz->cs, c);
165 rpmgz->rs.n = rpmgz->rs.sum = 0;
166 if (rpmgz->nb >= 2*CHUNK)
169 if (rpmgz->cs.size < CHUNK)
172 if (rpmgz->nb < CHUNK/2)
179 rsync_hint = rsync_next(&rpmgz->rs, c);
182 assert(rpmgz->nb >= RSYNC_WIN);
190 rsyncable_gzwrite(rpmGZFILE rpmgz,
const unsigned char *
const buf,
const size_t len)
195 ssize_t n_written = 0;
196 const unsigned char *begin = buf;
199 for (i = 0; i < len; i++) {
200 if (!sync_hint(rpmgz, buf[i]))
202 n = i + 1 - (begin - buf);
203 rc = gzwrite(rpmgz->gz, begin, (
unsigned)n);
205 return (n_written ? n_written : rc);
210 rc = gzflush(rpmgz->gz, Z_SYNC_FLUSH);
212 return (n_written ? n_written : rc);
214 if (begin < buf + len) {
215 n = len - (begin - buf);
216 rc = gzwrite(rpmgz->gz, begin, (
unsigned)n);
218 return (n_written ? n_written : rc);
227 static inline void * gzdFileno(
FD_t fd)
234 for (i = fd->
nfps; i >= 0; i--) {
236 if (fps->
io != gzdio)
246 FD_t gzdOpen(
const char * path,
const char * fmode)
252 mode_t mode = (fmode && fmode[0] ==
'w' ? O_WRONLY : O_RDONLY);
254 rpmgz =
xcalloc(1,
sizeof(*rpmgz));
255 rpmgz->gz = gzopen(path, fmode);
256 if (rpmgz->gz == NULL) {
257 rpmgz =
_free(rpmgz);
260 fd =
fdNew(
"open (gzdOpen)");
264 DBGIO(fd, (stderr,
"==>\tgzdOpen(\"%s\", \"%s\") fd %p %s\n", path, fmode, (fd ? fd : NULL),
fdbg(fd)));
265 return fdLink(fd,
"gzdOpen");
268 static FD_t gzdFdopen(
void * cookie,
const char *fmode)
276 if (fmode == NULL)
return NULL;
279 if (fdno < 0)
return NULL;
280 rpmgz =
xcalloc(1,
sizeof(*rpmgz));
281 rpmgz->gz = gzdopen(fdno, fmode);
282 if (rpmgz->gz == NULL) {
283 rpmgz =
_free(rpmgz);
287 fdPush(fd, gzdio, rpmgz, fdno);
289 return fdLink(fd,
"gzdFdopen");
292 static int gzdFlush(
void * cookie)
297 rpmgz = gzdFileno(fd);
298 if (rpmgz == NULL)
return -2;
299 return gzflush(rpmgz->gz, Z_SYNC_FLUSH);
304 static ssize_t gzdRead(
void * cookie,
char * buf,
size_t count)
314 rpmgz = gzdFileno(fd);
315 if (rpmgz == NULL)
return -2;
318 rc = gzread(rpmgz->gz, buf, (
unsigned)count);
319 DBGIO(fd, (stderr,
"==>\tgzdRead(%p,%p,%u) rc %lx %s\n", cookie, buf, (
unsigned)count, (
unsigned long)rc,
fdbg(fd)));
322 fd->
errcookie = gzerror(rpmgz->gz, &zerror);
323 if (zerror == Z_ERRNO) {
335 static ssize_t gzdWrite(
void * cookie,
const char * buf,
size_t count)
347 rpmgz = gzdFileno(fd);
348 if (rpmgz == NULL)
return -2;
352 rc = rsyncable_gzwrite(rpmgz, (
void *)buf, (
unsigned)count);
354 rc = gzwrite(rpmgz->gz, (
void *)buf, (
unsigned)count);
355 DBGIO(fd, (stderr,
"==>\tgzdWrite(%p,%p,%u) rc %lx %s\n", cookie, buf, (
unsigned)count, (
unsigned long)rc,
fdbg(fd)));
356 if (rc < (ssize_t)count) {
358 fd->
errcookie = gzerror(rpmgz->gz, &zerror);
359 if (zerror == Z_ERRNO) {
371 static inline int gzdSeek(
void * cookie,
_libio_pos_t pos,
int whence)
376 #if defined(HAVE_GZSEEK)
377 #ifdef USE_COOKIE_SEEK_POINTER
378 _IO_off64_t p = *pos;
385 if (fd == NULL)
return -2;
388 rpmgz = gzdFileno(fd);
389 if (rpmgz == NULL)
return -2;
392 rc = gzseek(rpmgz->gz, (
long)p, whence);
393 DBGIO(fd, (stderr,
"==>\tgzdSeek(%p,%ld,%d) rc %lx %s\n", cookie, (
long)p, whence, (
unsigned long)rc,
fdbg(fd)));
396 fd->
errcookie = gzerror(rpmgz->gz, &zerror);
397 if (zerror == Z_ERRNO) {
410 static int gzdClose(
void * cookie)
418 rpmgz = gzdFileno(fd);
419 if (rpmgz == NULL)
return -2;
423 rc = gzclose(rpmgz->gz);
427 rpmgz =
_free(rpmgz);
433 DBGIO(fd, (stderr,
"==>\tgzdClose(%p) zerror %d %s\n", cookie, rc,
fdbg(fd)));
440 }
else if (rc >= 0) {
445 DBGIO(fd, (stderr,
"==>\tgzdClose(%p) rc %lx %s\n", cookie, (
unsigned long)rc,
fdbg(fd)));
449 fd =
fdFree(fd,
"open (gzdClose)");
454 static struct FDIO_s gzdio_s = {
455 gzdRead, gzdWrite, gzdSeek, gzdClose, gzdOpen, gzdFdopen, gzdFlush,